home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume26 / arc-5.21 / part01 next >
Encoding:
Text File  |  1992-04-10  |  95.3 KB  |  3,417 lines

  1. Newsgroups: comp.sources.unix
  2. From: hyc@umix.cc.umich.edu (Howard Chu)
  3. Subject: v26i004: arc 5.21 (pl 8) - file archive/compression tool, Part01/03
  4. Sender: unix-sources-moderator@pa.dec.com
  5. Approved: vixie@pa.dec.com
  6.  
  7. Submitted-By: hyc@umix.cc.umich.edu (Howard Chu)
  8. Posting-Number: Volume 26, Issue 4
  9. Archive-Name: arc-5.21/part01
  10.  
  11. This program is based on the MSDOS ARC program, version 5.21, plus
  12. a few enhancements... It compiles on UNIX(tm) and on the Atari ST.
  13.  
  14.  o ARC also performs Huffman Squeezing on data. The Huffman Squeeze
  15.    algorithm was removed from MSDOS ARC after version 5.12. It turns
  16.    out to be more efficient than Lempel-Ziv style compression when
  17.    compressing graphic images. Squeeze analysis is always done now,
  18.    and the best of packing, squeezing, or crunching is used.
  19.  
  20.  o Compresses and extracts Squashed files. "Squashing" was created
  21.    by Phil Katz in his PKxxx series of ARC utility programs for
  22.    MSDOS. Dan Lanciani wrote the original modifications to ARC's
  23.    Crunch code to handle Squashing. I've made minor changes since
  24.    then, mostly to reduce the amount of memory required. The 'q'
  25.    option flag must be specified to Squash files. The Squashing
  26.    algorithm will be used instead of the usual Crunch algorithm,
  27.    and will be compared against packing and squeezing, as before.
  28.  
  29. #! /bin/sh
  30. # This is a shell archive.  Remove anything before this line, then unpack
  31. # it by saving it into a file and typing "sh file".  To overwrite existing
  32. # files, type "sh file -c".  You can also feed this as standard input via
  33. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  34. # will see the following message at the end:
  35. #        "End of archive 1 (of 3)."
  36. # Contents:  Arcinfo Changes.521 MANIFEST Makefile PATCHLEVEL README
  37. #   arc.h arccode.c arccvt.c arcdata.c arcdel.c arcdos.c arcext.c
  38. #   arcio.c arclst.c arcmatch.c arcpack.c arcrun.c arcs.h arcsvc.c
  39. #   arctst.c arcunp.c arcusq.c proto.h tmclock.c
  40. # Wrapped by vixie@cognition.pa.dec.com on Sat Apr 11 13:54:34 1992
  41. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  42. if test -f 'Arcinfo' -a "${1}" != "-c" ; then 
  43.   echo shar: Will not clobber existing file \"'Arcinfo'\"
  44. else
  45. echo shar: Extracting \"'Arcinfo'\" \(5577 characters\)
  46. sed "s/^X//" >'Arcinfo' <<'END_OF_FILE'
  47. X
  48. ARC-FILE.INF, created by Keith Petersen, W8SDZ, 21-Sep-86, extracted
  49. from UNARC.INF by Robert A. Freed.
  50. X
  51. XFrom:     Robert A. Freed
  52. Subject:  Technical Information for ARC files
  53. Date:     June 24, 1986
  54. X
  55. Note: In the following discussion, UNARC refers to my CP/M-80 program
  56. for extracting files from MSDOS ARCs.  The definitions of the ARC file
  57. format are based on MSDOS ARC512.EXE.
  58. X
  59. ARCHIVE FILE FORMAT
  60. X-------------------
  61. X
  62. Component files are stored sequentially within an archive.  Each entry
  63. is preceded by a 29-byte header, which contains the directory
  64. information.  There is no wasted space between entries.  (This is in
  65. contrast to the centralized directory used by Novosielski libraries.
  66. Although random access to subfiles within an archive can be noticeably
  67. slower than with libraries, archives do have the advantage of not
  68. requiring pre-allocation of directory space.)
  69. X
  70. Archive entries are normally maintained in sorted name order.  The
  71. format of the 29-byte archive header is as follows:
  72. X
  73. Byte 1:  1A Hex.
  74. X         This marks the start of an archive header.  If this byte is not found 
  75. X         when expected, UNARC will scan forward in the file (up to 64K bytes) 
  76. X         in an attempt to find it (followed by a valid compression version).  
  77. X         If a valid header is found in this manner, a warning message is 
  78. X         issued and archive file processing continues.  Otherwise, the file is 
  79. X         assumed to be an invalid archive and processing is aborted.  (This is 
  80. X         compatible with MS-DOS ARC version 5.12).  Note that a special 
  81. X         exception is made at the beginning of an archive file, to accomodate 
  82. X         "self-unpacking" archives (see below).
  83. X
  84. Byte 2:  Compression version, as follows:
  85. X
  86. X         0 = end of file marker (remaining bytes not present)
  87. X         1 = unpacked (obsolete)
  88. X         2 = unpacked
  89. X         3 = packed
  90. X         4 = squeezed (after packing)
  91. X         5 = crunched (obsolete)
  92. X         6 = crunched (after packing) (obsolete)
  93. X         7 = crunched (after packing, using faster hash algorithm) (obsolete)
  94. X         8 = crunched (after packing, using dynamic LZW variations)
  95. X
  96. Bytes 3-15:  ASCII file name, nul-terminated.
  97. X
  98. X(All of the following numeric values are stored low-byte first.)
  99. X
  100. Bytes 16-19:  Compressed file size in bytes.
  101. X
  102. Bytes 20-21:  File date, in 16-bit MS-DOS format:
  103. X              Bits 15:9 = year - 1980
  104. X              Bits  8:5 = month of year
  105. X              Bits  4:0 = day of month
  106. X              (All zero means no date.)
  107. X
  108. Bytes 22-23:  File time, in 16-bit MS-DOS format:
  109. X              Bits 15:11 = hour (24-hour clock)
  110. X              Bits 10:5  = minute
  111. X              Bits  4:0  = second/2 (not displayed by UNARC)
  112. X
  113. Bytes 24-25:  Cyclic redundancy check (CRC) value (see below).
  114. X
  115. Bytes 26-29:  Original (uncompressed) file length in bytes.
  116. X              (This field is not present for version 1 entries, byte 2 = 1.  
  117. X              I.e., in this case the header is only 25 bytes long.  Because 
  118. X              version 1 files are uncompressed, the value normally found in 
  119. X              this field may be obtained from bytes 16-19.)
  120. X
  121. X
  122. SELF-UNPACKING ARCHIVES
  123. X-----------------------
  124. X
  125. A "self-unpacking" archive is one which can be renamed to a .COM file
  126. and executed as a program.  An example of such a file is the MS-DOS
  127. program ARC512.COM, which is a standard archive file preceded by a
  128. three-byte jump instruction.  The first entry in this file is a simple
  129. X"bootstrap" program in uncompressed form, which loads the subfile
  130. ARC.EXE (also uncompressed) into memory and passes control to it.  In
  131. anticipation of a similar scheme for future distribution of UNARC, the
  132. program permits up to three bytes to precede the first header in an
  133. archive file (with no error message).
  134. X
  135. X
  136. CRC COMPUTATION
  137. X---------------
  138. X
  139. Archive files use a 16-bit cyclic redundancy check (CRC) for error
  140. control.  The particular CRC polynomial used is x^16 + x^15 + x^2 + 1,
  141. which is commonly known as "CRC-16" and is used in many data
  142. transmission protocols (e.g. DEC DDCMP and IBM BSC), as well as by
  143. most floppy disk controllers.  Note that this differs from the CCITT
  144. polynomial (x^16 + x^12 + x^5 + 1), which is used by the XMODEM-CRC
  145. protocol and the public domain CHEK program (although these do not
  146. adhere strictly to the CCITT standard).  The MS-DOS ARC program does
  147. perform a mathematically sound and accurate CRC calculation.  (We
  148. mention this because it contrasts with some unfortunately popular
  149. public domain programs we have witnessed, which from time immemorial
  150. have based their calculation on an obscure magazine article which
  151. contained a typographical error!)
  152. X
  153. Additional note (while we are on the subject of CRC's): The validity
  154. of using a 16-bit CRC for checking an entire file is somewhat
  155. questionable.  Many people quote the statistics related to these
  156. functions (e.g. "all two-bit errors, all single burst errors of 16 or
  157. fewer bits, 99.997% of all single 17-bit burst errors, etc."), without
  158. realizing that these claims are valid only if the total number of bits
  159. checked is less than 32767 (which is why they are used in small-packet
  160. data transmission protocols).  I.e., for file sizes in excess of about
  161. X4K bytes, a 16-bit CRC is not really as good as what is often claimed.
  162. This is not to say that it is bad, but there are more reliable methods
  163. available (e.g. the 32-bit AUTODIN-II polynomial).  (End of lecture!)
  164. X
  165. X                           Bob Freed
  166. X                           62 Miller Road
  167. X                           Newton Centre, MA  02159
  168. X                           Telephone (617) 332-3533
  169. X
  170. X
  171. END_OF_FILE
  172. if test 5577 -ne `wc -c <'Arcinfo'`; then
  173.     echo shar: \"'Arcinfo'\" unpacked with wrong size!
  174. fi
  175. # end of 'Arcinfo'
  176. fi
  177. if test -f 'Changes.521' -a "${1}" != "-c" ; then 
  178.   echo shar: Will not clobber existing file \"'Changes.521'\"
  179. else
  180. echo shar: Extracting \"'Changes.521'\" \(1892 characters\)
  181. sed "s/^X//" >'Changes.521' <<'END_OF_FILE'
  182. X                        CHANGES IN VERSION 5.21
  183. X
  184. X
  185. The following changes have been made in ARC version 5.21, but have not
  186. yet been included in the manual:
  187. X
  188. o   When adding files to an archive, ARC now shows the stowage facter
  189. X    achieved on each file.
  190. X
  191. o   A bug was found that would keep an archive entry from being
  192. X    encrypted if it was stored without compression.  This has now been
  193. X    fixed.
  194. X
  195. o   If changes are made to a corrupted archive, the corrupted entries
  196. X    are discarded.  This makes it possible to lose data accidentally.
  197. X    ARC will now only make changes to a corrupted archive if the W
  198. X    (suppress Warnings) option has been given.
  199. X
  200. o   The N (suppress Notes) option now suppresses the "Creating
  201. X    archive" note when a new archive is being created.
  202. X
  203. o   The N (suppress Notes) option formerly did nothing useful when
  204. X    used with the L (List files) command.  It now causes a terse
  205. X    listing of filenames only, suitable for use with pipes and
  206. X    redirection.
  207. X
  208. o   The list of filenames given to ARC may now include indirect
  209. X    references.  If a filename begins with an "at sign" ("@"), it is
  210. X    taken to be the name of a file which contains a list of file
  211. X    names.  The list of file names may include further indirection.
  212. X    If no extension is given, ".CMD" is assumed.  For example, the
  213. X    command:
  214. X
  215. X         arc a waste junk.txt @trash
  216. X
  217. X    would cause ARC to add JUNK.TXT plus all files listed in the file
  218. X    TRASH.CMD to an archive named WASTE.ARC.  If no file is specified,
  219. X    then the list is read from standard input.  For example, the
  220. X    command:
  221. X
  222. X         arc ln waste | arc a trash @
  223. X
  224. X    would cause ARC to add files to TRASH.ARC based on the names of
  225. X    the files stored in WASTE.ARC.  It is probably a good idea to give
  226. X    the O (Overwrite) option if you are extracting files this way.
  227. X
  228. X    Version 5.21 of MARC also allows for indirection.
  229. END_OF_FILE
  230. if test 1892 -ne `wc -c <'Changes.521'`; then
  231.     echo shar: \"'Changes.521'\" unpacked with wrong size!
  232. fi
  233. # end of 'Changes.521'
  234. fi
  235. if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  236.   echo shar: Will not clobber existing file \"'MANIFEST'\"
  237. else
  238. echo shar: Extracting \"'MANIFEST'\" \(1119 characters\)
  239. sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
  240. X   File Name        Archive #    Description
  241. X-----------------------------------------------------------
  242. X Arc521.doc                 3    
  243. X Arcinfo                    1    
  244. X Changes.521                1    
  245. X MANIFEST                   1    
  246. X Makefile                   1    
  247. X PATCHLEVEL                 1    
  248. X README                     1    
  249. X arc.1                      2    
  250. X arc.c                      2    
  251. X arc.h                      1    
  252. X arcadd.c                   2    
  253. X arccode.c                  1    
  254. X arccvt.c                   1    
  255. X arcdata.c                  1    
  256. X arcdel.c                   1    
  257. X arcdos.c                   1    
  258. X arcext.c                   1    
  259. X arcio.c                    1    
  260. X arclst.c                   1    
  261. X arclzw.c                   2    
  262. X arcmatch.c                 1    
  263. X arcmisc.c                  2    
  264. X arcpack.c                  1    
  265. X arcrun.c                   1    
  266. X arcs.h                     1    
  267. X arcsq.c                    2    
  268. X arcsvc.c                   1    
  269. X arctst.c                   1    
  270. X arcunp.c                   1    
  271. X arcusq.c                   1    
  272. X marc.c                     2    
  273. X proto.h                    1    
  274. X tmclock.c                  1    
  275. END_OF_FILE
  276. if test 1119 -ne `wc -c <'MANIFEST'`; then
  277.     echo shar: \"'MANIFEST'\" unpacked with wrong size!
  278. fi
  279. # end of 'MANIFEST'
  280. fi
  281. if test -f 'Makefile' -a "${1}" != "-c" ; then 
  282.   echo shar: Will not clobber existing file \"'Makefile'\"
  283. else
  284. echo shar: Extracting \"'Makefile'\" \(3858 characters\)
  285. sed "s/^X//" >'Makefile' <<'END_OF_FILE'
  286. X# $Header: /var/local/hyc/src/arc/RCS/Makefile,v 2.0 1991/11/12 00:45:33 hyc Exp $
  287. X#       Makefile for portable ARC
  288. X#
  289. X# Originals from Dan Lanciani, James Turner, and others...
  290. X# This Makefile supports Atari ST and all Unix versions.
  291. X#
  292. X# I put SRCDIR on a real disk on the ST, but copy the makefile to a
  293. X# RAMdisk and compile from there. Makes things go a bit quicker...
  294. X# This has to be done in the shell, to get the trailing backslash
  295. X# specified correctly. e.g., setenv SRCDIR='d:\src\arc\'
  296. SRCDIR = 
  297. X
  298. HEADER = $(SRCDIR)arc.h $(SRCDIR)arcs.h
  299. X
  300. X# Add a ".TTP" suffix to the executable files on an ST.
  301. X#PROG = .ttp
  302. PROG =
  303. X
  304. X# SYSTEM defines your operating system:
  305. X# MSDOS for IBM PCs or other MSDOS machines
  306. X# GEMDOS for Atari ST (Predefined by MWC, so you don't need to define it.)
  307. X# BSD for Berkeley Unix
  308. X# SYSV for AT&T System V Unix
  309. X# (_MTS for Michigan Terminal System, which requires a different makefile)
  310. X# (_MTS also requires one of USEGFINFO or USECATSCAN for directory search)
  311. X# NEEDMEMSET if your C library does not have the memset() routine and/or
  312. X# your system include doesn't have <memory.h> (Most current systems don't
  313. X# need this.)
  314. X#SYSTEM = -DGEMDOS=1 -fstrength-reduce -fcombine-regs -fforce-mem -fomit-frame-pointer -finline-functions -fforce-addr
  315. SYSTEM = -DBSD=1
  316. X
  317. OPT = -O
  318. X# For MWC 3.0 on the Atari ST, use:
  319. X#CFLAGS = -VCOMPAC -VPEEP
  320. CFLAGS = $(OPT) $(SYSTEM)
  321. X
  322. X# GNU's gcc is very nice, if you've got it. Otherwise just cc.
  323. X#CC = cgcc -mshort
  324. CC = cc
  325. X
  326. X# tmclock is only needed on Unix systems...
  327. TMCLOCK = tmclock.o
  328. X
  329. X# Files needed for System V 
  330. X#SYSVOBJ =    getwd.o rename.o scandir.o utimes.o
  331. SYSVOBJ =
  332. X
  333. OBJS = arc.o arcadd.o arccode.o arccvt.o arcdata.o arcdel.o arcdos.o \
  334. arcext.o arcio.o arclst.o arclzw.o arcmatch.o arcpack.o arcrun.o \
  335. arcsq.o arcsvc.o arctst.o arcunp.o arcusq.o arcmisc.o $(SYSVOBJ)
  336. X
  337. MOBJ = marc.o arcdata.o arcdos.o arcio.o arcmatch.o arcmisc.o $(SYSVOBJ)
  338. X
  339. all:    arc$(PROG) marc$(PROG)
  340. X
  341. arc$(PROG):    $(OBJS) $(TMCLOCK)
  342. X    $(CC) -o arc$(PROG) $(OBJS) $(TMCLOCK)
  343. X
  344. marc$(PROG):    $(MOBJ) $(TMCLOCK)
  345. X    $(CC) -o marc$(PROG) $(MOBJ) $(TMCLOCK)
  346. X
  347. clean:
  348. X    -rm *.o arc$(PROG) marc$(PROG)
  349. X
  350. arc.o:    $(SRCDIR)arc.c    $(HEADER)
  351. X    $(CC) $(CFLAGS) -c $(SRCDIR)arc.c
  352. marc.o:    $(SRCDIR)marc.c    $(HEADER)
  353. X    $(CC) $(CFLAGS) -c $(SRCDIR)marc.c
  354. arcadd.o:    $(SRCDIR)arcadd.c    $(HEADER)
  355. X    $(CC) $(CFLAGS) -c $(SRCDIR)arcadd.c
  356. arccode.o:    $(SRCDIR)arccode.c    $(HEADER)
  357. X    $(CC) $(CFLAGS) -c $(SRCDIR)arccode.c
  358. arccvt.o:    $(SRCDIR)arccvt.c    $(HEADER)
  359. X    $(CC) $(CFLAGS) -c $(SRCDIR)arccvt.c
  360. arcdata.o:    $(SRCDIR)arcdata.c    $(HEADER)
  361. X    $(CC) $(CFLAGS) -c $(SRCDIR)arcdata.c
  362. arcdel.o:    $(SRCDIR)arcdel.c    $(HEADER)
  363. X    $(CC) $(CFLAGS) -c $(SRCDIR)arcdel.c
  364. arcdir.o:    $(SRCDIR)arcdir.c    $(HEADER)
  365. X    $(CC) $(CFLAGS) -c $(SRCDIR)arcdir.c
  366. arcdos.o:    $(SRCDIR)arcdos.c    $(HEADER)
  367. X    $(CC) $(CFLAGS) -c $(SRCDIR)arcdos.c
  368. arcext.o:    $(SRCDIR)arcext.c    $(HEADER)
  369. X    $(CC) $(CFLAGS) -c $(SRCDIR)arcext.c
  370. arcio.o:    $(SRCDIR)arcio.c    $(HEADER)
  371. X    $(CC) $(CFLAGS) -c $(SRCDIR)arcio.c
  372. arclst.o:    $(SRCDIR)arclst.c    $(HEADER)
  373. X    $(CC) $(CFLAGS) -c $(SRCDIR)arclst.c
  374. arclzw.o:    $(SRCDIR)arclzw.c    $(HEADER)
  375. X    $(CC) $(CFLAGS) -c $(SRCDIR)arclzw.c
  376. arcmatch.o:    $(SRCDIR)arcmatch.c    $(HEADER)
  377. X    $(CC) $(CFLAGS) -c $(SRCDIR)arcmatch.c
  378. arcmisc.o:    $(SRCDIR)arcmisc.c    $(HEADER)
  379. X    $(CC) $(CFLAGS) -c $(SRCDIR)arcmisc.c
  380. arcpack.o:    $(SRCDIR)arcpack.c    $(HEADER)
  381. X    $(CC) $(CFLAGS) -c $(SRCDIR)arcpack.c
  382. arcrun.o:    $(SRCDIR)arcrun.c    $(HEADER)
  383. X    $(CC) $(CFLAGS) -c $(SRCDIR)arcrun.c
  384. arcsq.o:    $(SRCDIR)arcsq.c    $(HEADER)
  385. X    $(CC) $(CFLAGS) -c $(SRCDIR)arcsq.c
  386. arcsvc.o:    $(SRCDIR)arcsvc.c    $(HEADER)
  387. X    $(CC) $(CFLAGS) -c $(SRCDIR)arcsvc.c
  388. arctst.o:    $(SRCDIR)arctst.c    $(HEADER)
  389. X    $(CC) $(CFLAGS) -c $(SRCDIR)arctst.c
  390. arcunp.o:    $(SRCDIR)arcunp.c    $(HEADER)
  391. X    $(CC) $(CFLAGS) -c $(SRCDIR)arcunp.c
  392. arcusq.o:    $(SRCDIR)arcusq.c    $(HEADER)
  393. X    $(CC) $(CFLAGS) -c $(SRCDIR)arcusq.c
  394. X
  395. tmclock.o:    $(SRCDIR)tmclock.c
  396. X    $(CC) $(CFLAGS) -c $(SRCDIR)tmclock.c
  397. END_OF_FILE
  398. if test 3858 -ne `wc -c <'Makefile'`; then
  399.     echo shar: \"'Makefile'\" unpacked with wrong size!
  400. fi
  401. # end of 'Makefile'
  402. fi
  403. if test -f 'PATCHLEVEL' -a "${1}" != "-c" ; then 
  404.   echo shar: Will not clobber existing file \"'PATCHLEVEL'\"
  405. else
  406. echo shar: Extracting \"'PATCHLEVEL'\" \(2 characters\)
  407. sed "s/^X//" >'PATCHLEVEL' <<'END_OF_FILE'
  408. X8
  409. END_OF_FILE
  410. if test 2 -ne `wc -c <'PATCHLEVEL'`; then
  411.     echo shar: \"'PATCHLEVEL'\" unpacked with wrong size!
  412. fi
  413. # end of 'PATCHLEVEL'
  414. fi
  415. if test -f 'README' -a "${1}" != "-c" ; then 
  416.   echo shar: Will not clobber existing file \"'README'\"
  417. else
  418. echo shar: Extracting \"'README'\" \(5337 characters\)
  419. sed "s/^X//" >'README' <<'END_OF_FILE'
  420. Notes for ARC 5.21e                    October 31, 1991
  421. X
  422. X    ARC 5.21 for Unix is currently at patch level 8. The code provided
  423. here has been used on 4.3 BSD based Unix systems and on the Atari ST. (The
  424. GNU C compiler, version 1.40, was used to make the ST version. It should
  425. still compile with Mark Williams C, but I haven't bothered to try it.) The
  426. current version is over twice as fast as previous releases, for all file
  427. compression and decompression operations. It also fixes longstanding bugs
  428. in the squash code and in the tmclock DST code.
  429. X    The Arcinfo file describes the ARC 5.xx directory format. The 6.xx
  430. format contains additional information that is not supported here.
  431. X
  432. X    System V support in the shar file Sysvarcstuf was provided by Jon
  433. Zeeff, Janet Walz, and Rich Salz. You will probably also need the dirent
  434. directory library written by Doug Gwyn; this can be obtained from uunet or
  435. many other comp.sources.unix archive sites.
  436. X
  437. X    The tmclock.c file was stolen from Jef Poskanzer's tws library,
  438. as distributed in PHOON, PHase of the mOON, and slightly hacked by me.
  439. X
  440. X    The man page was originally from Leo Wilson, with updates by me.
  441. X
  442. X         /                 Howard Chu
  443. X   ___  /_ , ,_.     Jet Propulsion Laboratory
  444. X       / /(_/(__     hyc@hanauma.jpl.nasa.gov
  445. X           /
  446. X
  447. Notes for ARC 5.21                                        June 6, 1988
  448. This program is based on the MSDOS ARC program, version 5.21, plus
  449. a few enhancements... 
  450. X o ARC also performs Huffman Squeezing on data. The Huffman Squeeze
  451. X   algorithm was removed from MSDOS ARC after version 5.12. It turns
  452. X   out to be more efficient than Lempel-Ziv style compression when
  453. X   compressing graphic images. Squeeze analysis is always done now,
  454. X   and the best of packing, squeezing, or crunching is used.
  455. X o Compresses and extracts Squashed files. "Squashing" was created
  456. X   by Phil Katz in his PKxxx series of ARC utility programs for
  457. X   MSDOS. Dan Lanciani wrote the original modifications to ARC's
  458. X   Crunch code to handle Squashing. I've made minor changes since
  459. X   then, mostly to reduce the amount of memory required. The 'q'
  460. X   option flag must be specified to Squash files. The Squashing
  461. X   algorithm will be used instead of the usual Crunch algorithm,
  462. X   and will be compared against packing and squeezing, as before.
  463. System specific notes:
  464. X   On MTS, an additional option flag, 'i' for "image mode," was
  465. used. ARC assumes files are text, by default, and will translate
  466. MTS files from EBCDIC to ASCII before storing in an archive, and
  467. translates from ASCII to EBCDIC upon extraction. Specifying the
  468. X'i' flag will inhibit this translation. This would most commonly
  469. be used when shipping binary images such as TeX DVI files, other
  470. X.ARC files stored within an archive, etc... The 'r' (run) command
  471. is omitted. It just doesn't seem very useful. Also, ARC cannot
  472. restore MTS files with their original time stamps. (Maybe in a
  473. future release...)
  474. X   On Unix(tm) systems, the 'i' flag is also present. Unix ARC
  475. assumes a binary file, by default. Here the only translation
  476. involved is in end-of-line processing. When storing text files, ARC will
  477. change '\n' to '\r\n', and does the opposite when extracting files.
  478. Carriage returns in any other location are preserved when extracting.
  479. This translation only occurs if the 'i' flag is given.
  480. X
  481. X   On the Atari ST, the 'h' (for "hold screen") option is present,
  482. which simply delays exiting the program. This is typically used when
  483. executing ARC from the desktop, to allow reading all of ARC's output
  484. before the screen is cleared and the desktop is redrawn. The program
  485. will prompt and wait for a keypress before exiting. Note that since
  486. there are no "options" for the MARC program, the "hold screen" option
  487. is always active for MARC.
  488. X   On both Unix and Atari systems, ARC & MARC will search for an
  489. environment variable named "ARCTEMP" or "TMPDIR." If present, any
  490. temporary files will be created in the specified directory. This is
  491. probably insignificant for Unix users, but can be handy on the Atari,
  492. in combination with a RAMdisk. Highly recommended for floppy users.
  493. X(Unfortunately, you can only take advantage of this when running some
  494. form of command shell that allows setting environment variables. Thus,
  495. you won't see any speed gains when running from the desktop.)
  496. That about covers things. The enclosed documentation is taken directly
  497. from the MSDOS distribution of ARC. Unless specified differently here,
  498. the programs behave indentically. Note that ARC521.DOC is identical to
  499. ARC520.DOC - the differences between the two versions are described in
  500. the file CHANGES.521.
  501. Oh yeah - this program may be distributed freely so long as you don't
  502. modify it in any way. You may not charge for distributing it. (Don't
  503. feel bad, I can't charge for it either. }-) It'd be nice if you kept
  504. this and the other enclosed doc files with it when distributing, but
  505. I'm not going to make a fuss about it. Most people are so familiar
  506. with the program by now that it wouldn't matter much anyway. You
  507. should keep this README file around, so bug reports & such will find
  508. their way back to me. (Bugs? What bugs? Nah, there aren't any bugs...)
  509. X         /                 Howard Chu
  510. X   ___  /_ , ,_.     University of Michigan
  511. X       / /(_/(__     hyc@umix.cc.umich.edu
  512. X           /                umix!hyc
  513. X          '     
  514. END_OF_FILE
  515. if test 5337 -ne `wc -c <'README'`; then
  516.     echo shar: \"'README'\" unpacked with wrong size!
  517. fi
  518. # end of 'README'
  519. fi
  520. if test -f 'arc.h' -a "${1}" != "-c" ; then 
  521.   echo shar: Will not clobber existing file \"'arc.h'\"
  522. else
  523. echo shar: Extracting \"'arc.h'\" \(3401 characters\)
  524. sed "s/^X//" >'arc.h' <<'END_OF_FILE'
  525. X/*
  526. X * $Header: /var/local/hyc/src/arc/RCS/arc.h,v 2.0 1991/11/12 00:30:01 hyc Exp hyc $
  527. X */
  528. X
  529. X#undef    DOS    /* Just in case... */
  530. X#undef    UNIX
  531. X
  532. X/*
  533. X * Assumptions:
  534. X * char = 8 bits
  535. X * short = 16 bits
  536. X * long = 32 bits
  537. X * int >= 16 bits
  538. X */
  539. X
  540. X#if    MSDOS || GEMDOS
  541. X#define    DOS    1
  542. X#define    CUTOFF    '\\'
  543. X#define    OPEN_R    "rb"
  544. X#define    OPEN_W    "wb"
  545. X#if    __GNUC__
  546. X#include <types.h>
  547. X#include <string.h>
  548. X#endif
  549. X#endif
  550. X
  551. X#if    !MSDOS
  552. X#define    envfind    getenv
  553. X#define    setmem(a, b, c)    memset(a, c, b)
  554. X#endif
  555. X
  556. X#if    BSD || SYSV
  557. X#define    UNIX    1
  558. X#define    CUTOFF    '/'
  559. X#define    OPEN_R    "r"
  560. X#define    OPEN_W    "w"
  561. X#include <ctype.h>
  562. X#include <sys/types.h>
  563. X#endif
  564. X
  565. X#if    _MTS
  566. X#define    CUTOFF    sepchr[0]
  567. X#define    OPEN_R    "rb"
  568. X#define    OPEN_W    "wb"
  569. X#endif
  570. X
  571. X#define    MYBUF    32766        /* Used for fopens and filecopy() */
  572. X
  573. X#if    _MTS || SYSV
  574. X#define    rindex    strrchr
  575. X#define    index    strchr
  576. X#endif
  577. X
  578. X#if    __STDC__
  579. X#include <stdlib.h>
  580. X#define    VOID    void
  581. X#define    PROTO(args)    args
  582. X#else
  583. X#define    VOID    int
  584. X#define    PROTO(args)    ()
  585. X#endif
  586. X
  587. X/*  ARC - Archive utility - ARC Header
  588. X  
  589. X    Version 2.17, created on 04/22/87 at 13:09:43
  590. X  
  591. X(C) COPYRIGHT 1985,86 by System Enhancement Associates; ALL RIGHTS RESERVED
  592. X  
  593. X    By:     Thom Henderson
  594. X  
  595. X    Description: 
  596. X     This is the header file for the ARC archive utility.  It defines
  597. X     global parameters and the references to the external data.
  598. X  
  599. X  
  600. X    Language:
  601. X     Computer Innovations Optimizing C86
  602. X*/
  603. X
  604. X#define ARCMARK 26        /* special archive marker        */
  605. X#define ARCVER 9        /* archive header version code   */
  606. X#define STRLEN 100        /* system standard string length */
  607. X#define FNLEN 13        /* file name length              */
  608. X#define MAXARG 400        /* maximum number of arguments   */
  609. X
  610. X#if    !UNIX
  611. typedef unsigned int    u_int;
  612. X#ifndef    __GNUC__
  613. typedef unsigned char    u_char;
  614. typedef unsigned short    u_short;
  615. X#endif
  616. X#endif
  617. X#define    reg    register
  618. X
  619. X#ifndef DONT_DEFINE        /* Defined by arcdata.c */
  620. X#include "arcs.h"
  621. X
  622. extern int      keepbak;    /* true if saving the old archive */
  623. X#if    !DOS
  624. extern int      image;        /* true to suppress CRLF/LF x-late */
  625. X#endif
  626. X#if    _MTS
  627. extern char     sepchr[2];    /* Shared file separator, default = ':' */
  628. extern char     tmpchr[2];    /* Temporary file prefix, default = '-' */
  629. X#endif
  630. X#if    GEMDOS
  631. extern int      hold;        /* hold screen before exiting */
  632. X#endif
  633. extern int      warn;        /* true to print warnings */
  634. extern int      note;        /* true to print comments */
  635. extern int      bose;        /* true to be verbose */
  636. extern int      nocomp;        /* true to suppress compression */
  637. extern int      overlay;    /* true to overlay on extract */
  638. extern int      kludge;        /* kludge flag */
  639. extern char    *arctemp;    /* arc temp file prefix */
  640. extern char    *password;    /* encryption password pointer */
  641. extern int      nerrs;        /* number of errors encountered */
  642. extern int      changing;    /* true if archive being modified */
  643. X
  644. extern char     hdrver;        /* header version */
  645. X
  646. extern FILE    *arc;        /* the old archive */
  647. extern FILE    *new;        /* the new archive */
  648. extern char     arcname[STRLEN];/* storage for archive name */
  649. extern char     bakname[STRLEN];/* storage for backup copy name */
  650. extern char     newname[STRLEN];/* storage for new archive name */
  651. extern u_short    arcdate;    /* archive date stamp */
  652. extern u_short    arctime;    /* archive time stamp */
  653. extern u_short    olddate;    /* old archive date stamp */
  654. extern u_short    oldtime;    /* old archive time stamp */
  655. extern int      dosquash;    /* squash instead of crunch */
  656. X#endif                /* DONT_DEFINE */
  657. END_OF_FILE
  658. if test 3401 -ne `wc -c <'arc.h'`; then
  659.     echo shar: \"'arc.h'\" unpacked with wrong size!
  660. fi
  661. # end of 'arc.h'
  662. fi
  663. if test -f 'arccode.c' -a "${1}" != "-c" ; then 
  664.   echo shar: Will not clobber existing file \"'arccode.c'\"
  665. else
  666. echo shar: Extracting \"'arccode.c'\" \(1147 characters\)
  667. sed "s/^X//" >'arccode.c' <<'END_OF_FILE'
  668. X/*
  669. X * $Header: /var/local/hyc/src/arc/RCS/arccode.c,v 2.0 1991/11/12 00:30:01 hyc Exp $
  670. X */
  671. X
  672. X/*
  673. X * ARC - Archive utility - ARCCODE
  674. X * 
  675. X * Version 1.02, created on 01/20/86 at 13:33:35
  676. X * 
  677. X * (C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED
  678. X * 
  679. X * By:    Thom Henderson
  680. X * 
  681. X * Description: This file contains the routines used to encrypt and decrypt data
  682. X * in an archive.  The encryption method is nothing fancy, being just a
  683. X * routine XOR, but it is used on the packed data, and uses a variable length
  684. X * key.     The end result is something that is in theory crackable, but I'd
  685. X * hate to try it.  It should be more than sufficient for casual use.
  686. X * 
  687. X * Language: Computer Innovations Optimizing C86
  688. X */
  689. X#include <stdio.h>
  690. X#include "arc.h"
  691. X
  692. static char    *p;        /* password pointer */
  693. X
  694. VOID
  695. setcode()
  696. X{                /* get set for encoding/decoding */
  697. X    p = password;        /* reset password pointer */
  698. X}
  699. X
  700. VOID
  701. codebuf(buf, len)        /* encrypt a buffer */
  702. X    reg char       *buf;
  703. X    u_int        len;
  704. X{
  705. X    reg u_int    i;
  706. X    reg char       *pasptr = p;
  707. X
  708. X    for (i = 0; i < len; i++) {
  709. X        if (!*pasptr)
  710. X            pasptr = password;
  711. X        *buf++ ^= *pasptr++;
  712. X    }
  713. X    p = pasptr;
  714. X}
  715. END_OF_FILE
  716. if test 1147 -ne `wc -c <'arccode.c'`; then
  717.     echo shar: \"'arccode.c'\" unpacked with wrong size!
  718. fi
  719. # end of 'arccode.c'
  720. fi
  721. if test -f 'arccvt.c' -a "${1}" != "-c" ; then 
  722.   echo shar: Will not clobber existing file \"'arccvt.c'\"
  723. else
  724. echo shar: Extracting \"'arccvt.c'\" \(3539 characters\)
  725. sed "s/^X//" >'arccvt.c' <<'END_OF_FILE'
  726. X/*
  727. X * $Header: /var/local/hyc/src/arc/RCS/arccvt.c,v 2.0 1991/11/12 00:52:07 hyc Exp $
  728. X */
  729. X
  730. X/*
  731. X * ARC - Archive utility - ARCCVT
  732. X * 
  733. X * Version 1.16, created on 02/03/86 at 22:53:02
  734. X * 
  735. X * (C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED
  736. X * 
  737. X * By:  Thom Henderson
  738. X * 
  739. X * Description: This file contains the routines used to convert archives to use
  740. X * newer file storage methods.
  741. X * 
  742. X * Language: Computer Innovations Optimizing C86
  743. X */
  744. X#include <stdio.h>
  745. X#if    _MTS
  746. X#include <mts.h>
  747. X#endif
  748. X#include "arc.h"
  749. X
  750. int    match(), readhdr(), unpack(), unlink();
  751. VOID    openarc(), rempath(), closearc(), arcdie(), pack();
  752. VOID    writehdr(), filecopy();
  753. static    VOID    cvtfile();
  754. X
  755. static char     tempname[STRLEN];    /* temp file name */
  756. X
  757. VOID
  758. cvtarc(num, arg)        /* convert archive */
  759. X    int             num;    /* number of arguments */
  760. X    char           *arg[];    /* pointers to arguments */
  761. X{
  762. X    struct heads    hdr;    /* file header */
  763. X    int             cvt;    /* true to convert current file */
  764. X    int             did[MAXARG];/* true when argument was used */
  765. X    int             n;    /* index */
  766. X    char           *makefnam();    /* filename fixer */
  767. X    FILE           *fopen();/* file opener */
  768. X
  769. X    if (arctemp)        /* use temp area if specified */
  770. X        sprintf(tempname, "%s.CVT", arctemp);
  771. X    else
  772. X        makefnam("$ARCTEMP.CVT", arcname, tempname);
  773. X#if    !DOS
  774. X    image = 1;
  775. X#endif
  776. X
  777. X    openarc(1);        /* open archive for changes */
  778. X
  779. X    for (n = 0; n < num; n++)    /* for each argument */
  780. X        did[n] = 0;    /* reset usage flag */
  781. X    rempath(num, arg);    /* strip off paths */
  782. X
  783. X    if (num) {        /* if files were named */
  784. X        while (readhdr(&hdr, arc)) {    /* while more files to check */
  785. X            cvt = 0;/* reset convert flag */
  786. X            for (n = 0; n < num; n++) {    /* for each template
  787. X                             * given */
  788. X                if (match(hdr.name, arg[n])) {
  789. X                    cvt = 1;    /* turn on convert flag */
  790. X                    did[n] = 1;    /* turn on usage flag */
  791. X                    break;    /* stop looking */
  792. X                }
  793. X            }
  794. X
  795. X            if (cvt)/* if converting this one */
  796. X                cvtfile(&hdr);    /* then do it */
  797. X            else {    /* else just copy it */
  798. X                writehdr(&hdr, new);
  799. X                filecopy(arc, new, hdr.size);
  800. X            }
  801. X        }
  802. X    } else
  803. X        while (readhdr(&hdr, arc))    /* else convert all files */
  804. X            cvtfile(&hdr);
  805. X
  806. X    hdrver = 0;        /* archive EOF type */
  807. X    writehdr(&hdr, new);    /* write out our end marker */
  808. X    closearc(1);        /* close archive after changes */
  809. X
  810. X    if (note) {
  811. X        for (n = 0; n < num; n++) {    /* report unused args */
  812. X            if (!did[n]) {
  813. X                printf("File not found: %s\n", arg[n]);
  814. X                nerrs++;
  815. X            }
  816. X        }
  817. X    }
  818. X}
  819. X
  820. static    VOID
  821. cvtfile(hdr)            /* convert a file */
  822. X    struct heads   *hdr;    /* pointer to header data */
  823. X{
  824. X    long            starts, ftell();    /* where the file goes */
  825. X    FILE           *tmp, *fopen();    /* temporary file */
  826. X
  827. X    if (!(tmp = fopen(tempname, "w+b")))
  828. X        arcdie("Unable to create temporary file %s", tempname);
  829. X
  830. X    if (note) {
  831. X        printf("Converting file: %-12s   reading, ", hdr->name);
  832. X        fflush(stdout);
  833. X    }
  834. X    unpack(arc, tmp, hdr);    /* unpack the entry */
  835. X    fseek(tmp, 0L, 0);    /* reset temp for reading */
  836. X
  837. X    starts = ftell(new);    /* note where header goes */
  838. X    hdrver = ARCVER;        /* anything but end marker */
  839. X    writehdr(hdr, new);    /* write out header skeleton */
  840. X#if    _MTS
  841. X    atoe(hdr->name, FNLEN);    /* writehdr translated this... */
  842. X#endif
  843. X    pack(tmp, new, hdr);    /* pack file into archive */
  844. X    fseek(new, starts, 0);    /* move back to header skeleton */
  845. X    writehdr(hdr, new);    /* write out real header */
  846. X    fseek(new, hdr->size, 1);    /* skip over data to next header */
  847. X    fclose(tmp);        /* all done with the file */
  848. X    if (unlink(tempname) && warn) {
  849. X        printf("Cannot unsave %s\n", tempname);
  850. X        nerrs++;
  851. X    }
  852. X}
  853. END_OF_FILE
  854. if test 3539 -ne `wc -c <'arccvt.c'`; then
  855.     echo shar: \"'arccvt.c'\" unpacked with wrong size!
  856. fi
  857. # end of 'arccvt.c'
  858. fi
  859. if test -f 'arcdata.c' -a "${1}" != "-c" ; then 
  860.   echo shar: Will not clobber existing file \"'arcdata.c'\"
  861. else
  862. echo shar: Extracting \"'arcdata.c'\" \(2097 characters\)
  863. sed "s/^X//" >'arcdata.c' <<'END_OF_FILE'
  864. X/*
  865. X * $Header: /var/local/hyc/src/arc/RCS/arcdata.c,v 2.0 1991/11/12 00:34:06 hyc Exp $
  866. X */
  867. X
  868. X/*  ARC - Archive utility - ARCDATA
  869. X
  870. X    Version 2.17, created on 04/22/87 at 13:09:43
  871. X
  872. X(C) COPYRIGHT 1985,86 by System Enhancement Associates; ALL RIGHTS RESERVED
  873. X
  874. X    By:     Thom Henderson
  875. X
  876. X    Description: 
  877. X     This file defines the external data storage used by the ARC
  878. X     archive utility.
  879. X
  880. X
  881. X    Language:
  882. X     Computer Innovations Optimizing C86
  883. X*/
  884. X#include <stdio.h>
  885. X
  886. X#define DONT_DEFINE
  887. X#include "arc.h"
  888. X
  889. int             keepbak = 0;    /* true if saving the old archive */
  890. X#if    UNIX
  891. int        image = 1;    /* true to suppress CRLF/LF x-late */
  892. X#endif
  893. X#if    _MTS
  894. int             image = 0;    /* true to suppress EBCDIC/ASCII x-late */
  895. char            sepchr[2] = ":";/* Shared file separator */
  896. char            tmpchr[2] = "-";/* Temporary file prefix */
  897. X#endif
  898. X#if    GEMDOS
  899. int        hold = 0;    /* true to pause before exit */
  900. X#endif
  901. int             warn = 1;    /* true to print warnings */
  902. int             note = 1;    /* true to print comments */
  903. int             bose = 0;    /* true to be verbose */
  904. int             nocomp = 0;    /* true to suppress compression */
  905. int             overlay = 0;    /* true to overlay on extract */
  906. int             kludge = 0;    /* kludge flag */
  907. char           *arctemp = NULL;    /* arc temp file prefix */
  908. char           *password = NULL;/* encryption password pointer */
  909. int             nerrs = 0;    /* number of errors encountered */
  910. int        changing = 0;    /* true if archive being modified */
  911. X
  912. char            hdrver;        /* header version */
  913. X
  914. XFILE           *arc;        /* the old archive */
  915. XFILE           *new;        /* the new archive */
  916. char            arcname[STRLEN];    /* storage for archive name */
  917. char            bakname[STRLEN];    /* storage for backup copy name */
  918. char            newname[STRLEN];    /* storage for new archive name */
  919. unsigned short  arcdate = 0;    /* archive date stamp */
  920. unsigned short  arctime = 0;    /* archive time stamp */
  921. unsigned short  olddate = 0;    /* old archive date stamp */
  922. unsigned short  oldtime = 0;    /* old archive time stamp */
  923. int        dosquash = 0;    /* true to squash instead of crunch */
  924. END_OF_FILE
  925. if test 2097 -ne `wc -c <'arcdata.c'`; then
  926.     echo shar: \"'arcdata.c'\" unpacked with wrong size!
  927. fi
  928. # end of 'arcdata.c'
  929. fi
  930. if test -f 'arcdel.c' -a "${1}" != "-c" ; then 
  931.   echo shar: Will not clobber existing file \"'arcdel.c'\"
  932. else
  933. echo shar: Extracting \"'arcdel.c'\" \(2086 characters\)
  934. sed "s/^X//" >'arcdel.c' <<'END_OF_FILE'
  935. X/*
  936. X * $Header: /var/local/hyc/src/arc/RCS/arcdel.c,v 2.0 1991/11/12 00:30:01 hyc Exp $
  937. X */
  938. X
  939. X/*
  940. X * ARC - Archive utility - ARCDEL
  941. X * 
  942. X * Version 2.09, created on 02/03/86 at 22:53:27
  943. X * 
  944. X * (C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED
  945. X * 
  946. X * By:  Thom Henderson
  947. X * 
  948. X * Description: This file contains the routines used to delete entries in an
  949. X * archive.
  950. X * 
  951. X * Language: Computer Innovations Optimizing C86
  952. X */
  953. X#include <stdio.h>
  954. X#include "arc.h"
  955. X
  956. VOID    arcdie(), rempath(), openarc(), closearc(), writehdr(), filecopy();
  957. int    match(), readhdr();
  958. X
  959. VOID
  960. delarc(num, arg)        /* remove files from archive */
  961. X    int             num;    /* number of arguments */
  962. X    char           *arg[];    /* pointers to arguments */
  963. X{
  964. X    struct heads    hdr;    /* header data */
  965. X    int             del;    /* true to delete a file */
  966. X    int             did[MAXARG];/* true when argument used */
  967. X    int             n;    /* index */
  968. X
  969. X    if (!num)        /* she must specify which */
  970. X        arcdie("You must tell me which files to delete!");
  971. X
  972. X    for (n = 0; n < num; n++)    /* for each argument */
  973. X        did[n] = 0;    /* reset usage flag */
  974. X    rempath(num, arg);    /* strip off paths */
  975. X
  976. X    openarc(1);        /* open archive for changes */
  977. X
  978. X    while (readhdr(&hdr, arc)) {    /* while more entries in archive */
  979. X        del = 0;    /* reset delete flag */
  980. X        for (n = 0; n < num; n++) {    /* for each template given */
  981. X            if (match(hdr.name, arg[n])) {
  982. X                del = 1;    /* turn on delete flag */
  983. X                did[n] = 1;    /* turn on usage flag */
  984. X                break;    /* stop looking */
  985. X            }
  986. X        }
  987. X
  988. X        if (del) {    /* skip over unwanted files */
  989. X            fseek(arc, hdr.size, 1);
  990. X            if (note)
  991. X                printf("Deleting file: %s\n", hdr.name);
  992. X        } else {    /* else copy over file data */
  993. X            writehdr(&hdr, new);    /* write out header and file */
  994. X            filecopy(arc, new, hdr.size);
  995. X        }
  996. X    }
  997. X
  998. X    hdrver = 0;        /* special end of archive type */
  999. X    writehdr(&hdr, new);    /* write out archive end marker */
  1000. X    closearc(1);        /* close archive after changes */
  1001. X
  1002. X    if (note) {
  1003. X        for (n = 0; n < num; n++) {    /* report unused arguments */
  1004. X            if (!did[n]) {
  1005. X                printf("File not found: %s\n", arg[n]);
  1006. X                nerrs++;
  1007. X            }
  1008. X        }
  1009. X    }
  1010. X}
  1011. END_OF_FILE
  1012. if test 2086 -ne `wc -c <'arcdel.c'`; then
  1013.     echo shar: \"'arcdel.c'\" unpacked with wrong size!
  1014. fi
  1015. # end of 'arcdel.c'
  1016. fi
  1017. if test -f 'arcdos.c' -a "${1}" != "-c" ; then 
  1018.   echo shar: Will not clobber existing file \"'arcdos.c'\"
  1019. else
  1020. echo shar: Extracting \"'arcdos.c'\" \(4711 characters\)
  1021. sed "s/^X//" >'arcdos.c' <<'END_OF_FILE'
  1022. X/*
  1023. X * $Header: /var/local/hyc/src/arc/RCS/arcdos.c,v 2.0 1991/11/12 00:34:06 hyc Exp $
  1024. X */
  1025. X
  1026. X/*
  1027. X * ARC - Archive utility - ARCDOS
  1028. X * 
  1029. X * Version 1.44, created on 07/25/86 at 14:17:38
  1030. X * 
  1031. X * (C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED
  1032. X * 
  1033. X * By:  Thom Henderson
  1034. X * 
  1035. X * Description: This file contains certain DOS level routines that assist in
  1036. X * doing fancy things with an archive, primarily reading and setting the date
  1037. X * and time last modified.
  1038. X * 
  1039. X * These are, by nature, system dependant functions.  But they are also, by
  1040. X * nature, very expendable.
  1041. X * 
  1042. X * Language: Computer Innovations Optimizing C86
  1043. X */
  1044. X#include <stdio.h>
  1045. X#include "arc.h"
  1046. X
  1047. X#if    MSDOS
  1048. X#include "fileio2.h"        /* needed for filehand */
  1049. X#endif
  1050. X
  1051. X#if    UNIX
  1052. X#include <sys/types.h>
  1053. X#include <sys/stat.h>
  1054. X#if    BSD
  1055. X#include <sys/time.h>
  1056. X#else    
  1057. X#include <time.h>        /* Sys V. Bleah. */
  1058. struct    timeval {
  1059. X    long    tv_sec;
  1060. X    long    tv_usec;
  1061. X};
  1062. X#endif    /* BSD vs SYSV */
  1063. X#endif
  1064. X
  1065. X#if    GEMDOS
  1066. X#include <osbind.h>
  1067. X#endif
  1068. X
  1069. X#include <string.h>
  1070. X#ifndef    __STDC__
  1071. char    *malloc();
  1072. X#endif
  1073. X
  1074. VOID
  1075. getstamp(f, date, time)        /* get a file's date/time stamp */
  1076. X#if    !_MTS
  1077. X    FILE           *f;    /* file to get stamp from */
  1078. X#else
  1079. X    char           *f;    /* filename "" "" */
  1080. X#endif
  1081. X    unsigned short   *date, *time;    /* storage for the stamp */
  1082. X{
  1083. X#if    MSDOS
  1084. X    struct {
  1085. X        int             ax, bx, cx, dx, si, di, ds, es;
  1086. X    }               reg;
  1087. X
  1088. X    reg.ax = 0x5700;    /* get date/time */
  1089. X    reg.bx = filehand(f);    /* file handle */
  1090. X    if (sysint21(®, ®) & 1)    /* DOS call */
  1091. X        printf("Get timestamp fail (%d)\n", reg.ax);
  1092. X
  1093. X    *date = reg.dx;        /* save date/time */
  1094. X    *time = reg.cx;
  1095. X#endif
  1096. X#if    GEMDOS
  1097. X    int    fd, ret[2];
  1098. X
  1099. X    fd = fileno(f);
  1100. X    Fdatime(ret, fd, 0);
  1101. X    *date = ret[1];
  1102. X    *time = ret[0];
  1103. X#endif
  1104. X#if    UNIX
  1105. X    struct stat    buf;
  1106. X    struct tm    *localtime(), *t;
  1107. X
  1108. X    fstat(fileno(f), &buf);
  1109. X    t=localtime(&(buf.st_mtime));
  1110. X    *date = (unsigned short) (((t->tm_year - 80) << 9) +
  1111. X                ((t->tm_mon + 1) << 5) + t->tm_mday);
  1112. X    *time = (unsigned short) ((t->tm_hour << 11) +
  1113. X                (t->tm_min << 5) + t->tm_sec / 2);
  1114. X#endif
  1115. X#if    _MTS
  1116. X    fortran         timein(),
  1117. X#if    USEGFINFO
  1118. X                    gfinfo();
  1119. X#else
  1120. X                    fileinfo();
  1121. X#endif
  1122. X    int             stclk[2];
  1123. X    char            name[24];
  1124. X    struct bigtime {
  1125. X        int             greg;
  1126. X        int             year;
  1127. X        int             mon;
  1128. X        int             day;
  1129. X        int             hour;
  1130. X        int             min;
  1131. X        int             sec;
  1132. X        int             usec;
  1133. X        int             week;
  1134. X        int             toff;
  1135. X        int             tzn1;
  1136. X        int             tzn2;
  1137. X    }               tvec;
  1138. X#if    USEGFINFO
  1139. X    static int      gfflag = 0x0009, gfdummy[2] = {
  1140. X                               0, 0
  1141. X    };
  1142. X    int             gfcinfo[18];
  1143. X#else
  1144. X    static int      cattype = 2;
  1145. X#endif
  1146. X
  1147. X    strcpy(name, f);
  1148. X    strcat(name, " ");
  1149. X#if    USEGFINFO
  1150. X    gfcinfo[0] = 18;
  1151. X    gfinfo(name, name, &gfflag, gfcinfo, gfdummy, gfdummy);
  1152. X    timein("*IBM MICROSECONDS*", &gfcinfo[16], &tvec);
  1153. X#else
  1154. X    fileinfo(name, &cattype, "CILCCT  ", stclk);
  1155. X    timein("*IBM MICROSECONDS*", stclk, &tvec);
  1156. X#endif
  1157. X
  1158. X    *date = (unsigned short) (((tvec.year - 1980) << 9) + ((tvec.mon) << 5) + tvec.day);
  1159. X    *time = (unsigned short) ((tvec.hour << 11) + (tvec.min << 5) + tvec.sec / 2);
  1160. X#endif
  1161. X}
  1162. X
  1163. VOID
  1164. setstamp(f, date, time)        /* set a file's date/time stamp */
  1165. X    char           *f;    /* filename to stamp */
  1166. X    unsigned short    date, time;    /* desired date, time */
  1167. X{
  1168. X#if    MSDOS
  1169. X    FILE    *ff;
  1170. X    struct {
  1171. X        int             ax, bx, cx, dx, si, di, ds, es;
  1172. X    }               reg;
  1173. X
  1174. X    ff = fopen(f, "w+");    /* How else can I get a handle? */
  1175. X
  1176. X    reg.ax = 0x5701;    /* set date/time */
  1177. X    reg.bx = filehand(f);    /* file handle */
  1178. X    reg.cx = time;        /* desired time */
  1179. X    reg.dx = date;        /* desired date */
  1180. X    if (sysint21(®, ®) & 1)    /* DOS call */
  1181. X        printf("Set timestamp fail (%d)\n", reg.ax);
  1182. X    fclose(ff);
  1183. X#endif
  1184. X#if    GEMDOS
  1185. X    int    fd, set[2];
  1186. X
  1187. X    fd = Fopen(f, 0);
  1188. X    set[0] = time;
  1189. X    set[1] = date;
  1190. X    Fdatime(set, fd, 1);
  1191. X    Fclose(fd);
  1192. X#endif
  1193. X#if    UNIX
  1194. X    struct tm    tm;
  1195. X    struct timeval  tvp[2];
  1196. X    int    utimes();
  1197. X    long    tmclock();
  1198. X    tm.tm_sec = (time & 31) * 2;
  1199. X    tm.tm_min = (time >> 5) & 63;
  1200. X    tm.tm_hour = (time >> 11);
  1201. X    tm.tm_mday = date & 31;
  1202. X    tm.tm_mon = ((date >> 5) & 15) - 1;
  1203. X    tm.tm_year = (date >> 9) + 80;
  1204. X    tvp[0].tv_sec = tmclock(&tm);
  1205. X    tvp[1].tv_sec = tvp[0].tv_sec;
  1206. X    tvp[0].tv_usec = tvp[1].tv_usec = 0;
  1207. X    utimes(f, tvp);
  1208. X#endif
  1209. X}
  1210. X
  1211. X#if    MSDOS
  1212. int
  1213. filehand(stream)        /* find handle on a file */
  1214. X    struct bufstr  *stream;    /* file to grab onto */
  1215. X{
  1216. X    return stream->bufhand;    /* return DOS 2.0 file handle */
  1217. X}
  1218. X#endif
  1219. X
  1220. X#if    UNIX
  1221. int
  1222. izadir(filename)        /* Is filename a directory? */
  1223. X    char           *filename;
  1224. X{
  1225. X    struct stat     buf;
  1226. X
  1227. X    if (stat(filename, &buf) != 0)
  1228. X        return (0);    /* Ignore if stat fails since */
  1229. X    else
  1230. X        return (buf.st_mode & S_IFDIR);    /* bad files trapped later */
  1231. X}
  1232. X#endif
  1233. END_OF_FILE
  1234. if test 4711 -ne `wc -c <'arcdos.c'`; then
  1235.     echo shar: \"'arcdos.c'\" unpacked with wrong size!
  1236. fi
  1237. # end of 'arcdos.c'
  1238. fi
  1239. if test -f 'arcext.c' -a "${1}" != "-c" ; then 
  1240.   echo shar: Will not clobber existing file \"'arcext.c'\"
  1241. else
  1242. echo shar: Extracting \"'arcext.c'\" \(4978 characters\)
  1243. sed "s/^X//" >'arcext.c' <<'END_OF_FILE'
  1244. X/*
  1245. X * $Header: /var/local/hyc/src/arc/RCS/arcext.c,v 2.0 1991/11/12 02:32:55 hyc Exp $
  1246. X */
  1247. X
  1248. X/*
  1249. X * ARC - Archive utility - ARCEXT
  1250. X * 
  1251. X * Version 2.19, created on 10/24/86 at 14:53:32
  1252. X * 
  1253. X * (C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED
  1254. X * 
  1255. X * By:  Thom Henderson
  1256. X * 
  1257. X * Description: This file contains the routines used to extract files from an
  1258. X * archive.
  1259. X * 
  1260. X * Language: Computer Innovations Optimizing C86
  1261. X */
  1262. X#include <stdio.h>
  1263. X#include "arc.h"
  1264. X#if    !MSDOS
  1265. X#include <ctype.h>
  1266. X#endif
  1267. X#include <string.h>
  1268. X#if    BSD
  1269. X#include <strings.h>
  1270. X#endif
  1271. X
  1272. VOID    openarc(), closearc(), setstamp();
  1273. int    match(), readhdr(), unpack();
  1274. static    VOID    extfile();
  1275. X
  1276. X#ifndef    __STDC__
  1277. char    *malloc();
  1278. X#ifndef _AIX
  1279. VOID    free();
  1280. X#endif
  1281. X#endif
  1282. X
  1283. VOID
  1284. extarc(num, arg, prt)        /* extract files from archive */
  1285. X    int             num;    /* number of arguments */
  1286. X    char           *arg[];    /* pointers to arguments */
  1287. X    int             prt;        /* true if printing */
  1288. X{
  1289. X    struct heads    hdr;    /* file header */
  1290. X    int             save;    /* true to save current file */
  1291. X    int             did[MAXARG];/* true when argument was used */
  1292. X    char           *i;    /* string index */
  1293. X    char          **name;     /* name pointer list */
  1294. X    int             n;    /* index */
  1295. X
  1296. X    name = (char **) malloc(num * sizeof(char *));    /* get storage for name
  1297. X                             * pointers */
  1298. X
  1299. X    for (n = 0; n < num; n++) {    /* for each argument */
  1300. X        did[n] = 0;    /* reset usage flag */
  1301. X#if    !_MTS
  1302. X        if (!(i = rindex(arg[n], '\\')))    /* find start of name */
  1303. X            if (!(i = rindex(arg[n], '/')))
  1304. X                if (!(i = rindex(arg[n], ':')))
  1305. X                    i = arg[n] - 1;
  1306. X#else
  1307. X        if (!(i = rindex(arg[n], sepchr[0])))
  1308. X            if (arg[n][0] != tmpchr[0])
  1309. X                i = arg[n] - 1;
  1310. X            else
  1311. X                i = arg[n];
  1312. X#endif
  1313. X        name[n] = i + 1;
  1314. X    }
  1315. X
  1316. X
  1317. X    openarc(0);        /* open archive for reading */
  1318. X
  1319. X    if (num) {        /* if files were named */
  1320. X        while (readhdr(&hdr, arc)) {    /* while more files to check */
  1321. X            save = 0;    /* reset save flag */
  1322. X            for (n = 0; n < num; n++) {    /* for each template
  1323. X                             * given */
  1324. X                if (match(hdr.name, name[n])) {
  1325. X                    save = 1;    /* turn on save flag */
  1326. X                    did[n] = 1;    /* turn on usage flag */
  1327. X                    break;    /* stop looking */
  1328. X                }
  1329. X            }
  1330. X
  1331. X            if (save)    /* extract if desired, else skip */
  1332. X                extfile(&hdr, arg[n], prt);
  1333. X            else
  1334. X                fseek(arc, hdr.size, 1);
  1335. X        }
  1336. X    } else
  1337. X        while (readhdr(&hdr, arc))    /* else extract all files */
  1338. X            extfile(&hdr, "", prt);
  1339. X
  1340. X    closearc(0);        /* close archive after reading */
  1341. X
  1342. X    if (note) {
  1343. X        for (n = 0; n < num; n++) {    /* report unused args */
  1344. X            if (!did[n]) {
  1345. X                printf("File not found: %s\n", arg[n]);
  1346. X                nerrs++;
  1347. X            }
  1348. X        }
  1349. X    }
  1350. X    free(name);
  1351. X}
  1352. X
  1353. static VOID
  1354. extfile(hdr, path, prt)        /* extract a file */
  1355. X    struct heads   *hdr;    /* pointer to header data */
  1356. X    char           *path;    /* pointer to path name */
  1357. X    int             prt;    /* true if printing */
  1358. X{
  1359. X    FILE           *f, *fopen();    /* extracted file, opener */
  1360. X    char            buf[STRLEN];    /* input buffer */
  1361. X    char            fix[STRLEN];    /* fixed name buffer */
  1362. X    char           *i;    /* string index */
  1363. X
  1364. X    if (prt) {        /* printing is much easier */
  1365. X        unpack(arc, stdout, hdr);    /* unpack file from archive */
  1366. X        printf("\f");    /* eject the form */
  1367. X        return;        /* see? I told you! */
  1368. X    }
  1369. X    strcpy(fix, path);    /* note path name template */
  1370. X#if    !_MTS
  1371. X    if (*path) {
  1372. X    if (!(i = rindex(fix, '\\')))    /* find start of name */
  1373. X        if (!(i = rindex(fix, '/')))
  1374. X            if (!(i = rindex(fix, ':')))
  1375. X                i = fix - 1;
  1376. X    } else i = fix -1;
  1377. X#else
  1378. X    if (!(i = rindex(fix, sepchr[0])))
  1379. X        if (fix[0] != tmpchr[0])
  1380. X            i = fix - 1;
  1381. X        else
  1382. X            i = fix;
  1383. X#endif
  1384. X    strcpy(i + 1, hdr->name);    /* replace template with name */
  1385. X
  1386. X    if (note)
  1387. X        printf("Extracting file: %s\n", fix);
  1388. X
  1389. X    if (warn && !overlay) {
  1390. X        if (f = fopen(fix, "r")) {    /* see if it exists */
  1391. X                fclose(f);
  1392. X                printf("WARNING: File %s already exists!", fix);
  1393. X                fflush(stdout);
  1394. X                while (1) {
  1395. X                    printf("  Overwrite it (y/n)? ");
  1396. X                    fflush(stdout);
  1397. X                    fgets(buf, STRLEN, stdin);
  1398. X                    *buf = toupper(*buf);
  1399. X                    if (*buf == 'Y' || *buf == 'N')
  1400. X                        break;
  1401. X                }
  1402. X                if (*buf == 'N') {
  1403. X                    printf("%s not extracted.\n", fix);
  1404. X                    fseek(arc, hdr->size, 1);
  1405. X                    return;
  1406. X                }
  1407. X        }
  1408. X    }
  1409. X#if    !_MTS
  1410. X    if (!(f = fopen(fix, OPEN_W)))
  1411. X#else
  1412. X    {
  1413. X        fortran         create();
  1414. X        VOID        memset();
  1415. X        char            c_name[256];
  1416. X        struct crsize {
  1417. X            short           maxsize, cursize;
  1418. X        }               c_size;
  1419. X        char            c_vol[6];
  1420. X        int             c_type;
  1421. X        strcpy(c_name, fix);
  1422. X        strcat(c_name, " ");
  1423. X        c_size.maxsize = 0;
  1424. X        c_size.cursize = hdr->length / 4096 + 1;
  1425. X        memset(c_vol, 0, sizeof(c_vol));
  1426. X        c_type = 0x100;
  1427. X        create(c_name, &c_size, c_vol, &c_type);
  1428. X    }
  1429. X    if (image) {
  1430. X        f = fopen(fix, OPEN_W);
  1431. X    } else
  1432. X        f = fopen(fix, "w");
  1433. X    if (!f)
  1434. X#endif
  1435. X    {
  1436. X        if (warn) {
  1437. X            printf("Cannot create %s\n", fix);
  1438. X            nerrs++;
  1439. X        }
  1440. X        fseek(arc, hdr->size, 1);
  1441. X        return;
  1442. X    }
  1443. X
  1444. X    /* now unpack the file */
  1445. X
  1446. X    unpack(arc, f, hdr);    /* unpack file from archive */
  1447. X    fclose(f);        /* all done writing to file */
  1448. X#if    !_MTS
  1449. X    setstamp(fix, hdr->date, hdr->time);    /* use filename for stamp */
  1450. X#endif
  1451. X}
  1452. END_OF_FILE
  1453. if test 4978 -ne `wc -c <'arcext.c'`; then
  1454.     echo shar: \"'arcext.c'\" unpacked with wrong size!
  1455. fi
  1456. # end of 'arcext.c'
  1457. fi
  1458. if test -f 'arcio.c' -a "${1}" != "-c" ; then 
  1459.   echo shar: Will not clobber existing file \"'arcio.c'\"
  1460. else
  1461. echo shar: Extracting \"'arcio.c'\" \(6860 characters\)
  1462. sed "s/^X//" >'arcio.c' <<'END_OF_FILE'
  1463. X/*
  1464. X * $Header: /var/local/hyc/src/arc/RCS/arcio.c,v 2.0 1991/11/12 02:34:42 hyc Exp $
  1465. X */
  1466. X
  1467. X/*  ARC - Archive utility - ARCIO
  1468. X
  1469. X    Version 2.50, created on 04/22/87 at 13:25:20
  1470. X
  1471. X(C) COPYRIGHT 1985,86 by System Enhancement Associates; ALL RIGHTS RESERVED
  1472. X
  1473. X    By:     Thom Henderson
  1474. X
  1475. X    Description:
  1476. X     This file contains the file I/O routines used to manipulate
  1477. X     an archive.
  1478. X
  1479. X    Language:
  1480. X     Computer Innovations Optimizing C86
  1481. X*/
  1482. X#include <stdio.h>
  1483. X#include "arc.h"
  1484. X#if    _MTS
  1485. X#include <mts.h>
  1486. X#endif
  1487. X#include <string.h>
  1488. X
  1489. VOID    arcdie();
  1490. X
  1491. int
  1492. readhdr(hdr, f)            /* read a header from an archive */
  1493. X    struct heads   *hdr;    /* storage for header */
  1494. X    FILE           *f;    /* archive to read header from */
  1495. X{
  1496. X#if    !MSDOS
  1497. X    unsigned char   dummy[28];
  1498. X    int             i;
  1499. X#endif
  1500. X    char            name[FNLEN];    /* filename buffer */
  1501. X    int             try = 0;/* retry counter */
  1502. X    static int      first = 1;    /* true only on first read */
  1503. X
  1504. X    if (!f)            /* if archive didn't open */
  1505. X        return 0;    /* then pretend it's the end */
  1506. X    hdrver = fgetc(f);
  1507. X    if (feof(f))        /* if no more data */
  1508. X        return 0;    /* then signal end of archive */
  1509. X
  1510. X    if (hdrver != ARCMARK) {    /* check archive validity */
  1511. X        if (warn) {
  1512. X            printf("An entry in %s has a bad header.\n", arcname);
  1513. X            nerrs++;
  1514. X        }
  1515. X        printf("hdrver: %x\n", hdrver);
  1516. X        while (!feof(f)) {
  1517. X            try++;
  1518. X            if (fgetc(f) == ARCMARK) {
  1519. X                ungetc(hdrver = fgetc(f), f);
  1520. X                if (!(hdrver & 0x80) && hdrver <= ARCVER)
  1521. X                    break;
  1522. X            }
  1523. X        }
  1524. X
  1525. X        if (feof(f) && first)
  1526. X            arcdie("%s is not an archive", arcname);
  1527. X
  1528. X        if (changing && warn)
  1529. X            arcdie("%s is corrupted -- changes disallowed", arcname);
  1530. X
  1531. X        if (warn)
  1532. X            printf("  %d bytes skipped.\n", try);
  1533. X
  1534. X        if (feof(f))
  1535. X            return 0;
  1536. X    }
  1537. X    hdrver = fgetc(f);    /* get header version */
  1538. X    if (hdrver & 0x80)    /* sign bit? negative? */
  1539. X        arcdie("Invalid header in archive %s", arcname);
  1540. X    if (hdrver == 0)
  1541. X        return 0;    /* note our end of archive marker */
  1542. X    if (hdrver > ARCVER) {
  1543. X        fread(name, sizeof(char), FNLEN, f);
  1544. X#if    _MTS
  1545. X        atoe(name, strlen(name));
  1546. X#endif
  1547. X        printf("I don't know how to handle file %s in archive %s\n",
  1548. X               name, arcname);
  1549. X        printf("I think you need a newer version of ARC.\n");
  1550. X        exit(1);
  1551. X    }
  1552. X    /* amount to read depends on header type */
  1553. X
  1554. X    if (hdrver == 1) {    /* old style is shorter */
  1555. X        fread(hdr, sizeof(struct heads) - sizeof(long int), 1, f);
  1556. X        hdrver = 2;    /* convert header to new format */
  1557. X        hdr->length = hdr->size;    /* size is same when not
  1558. X                         * packed */
  1559. X    } else
  1560. X#if    MSDOS
  1561. X        fread(hdr, sizeof(struct heads), 1, f);
  1562. X#else
  1563. X        fread(dummy, 27, 1, f);
  1564. X
  1565. X    for (i = 0; i < FNLEN; hdr->name[i] = dummy[i], i++);
  1566. X#if    _MTS
  1567. X    (void) atoe(hdr->name, strlen(hdr->name));
  1568. X#endif
  1569. X    for (i = 0, hdr->size=0; i<4; hdr->size<<=8, hdr->size += dummy[16-i], i++);
  1570. X    hdr->date = (short) ((dummy[18] << 8) + dummy[17]);
  1571. X    hdr->time = (short) ((dummy[20] << 8) + dummy[19]);
  1572. X    hdr->crc = (short) ((dummy[22] << 8) + dummy[21]);
  1573. X    for (i = 0, hdr->length=0; i<4; hdr->length<<=8, hdr->length += dummy[26-i], i++);
  1574. X#endif
  1575. X
  1576. X    if (hdr->date > olddate
  1577. X        || (hdr->date == olddate && hdr->time > oldtime)) {
  1578. X        olddate = hdr->date;
  1579. X        oldtime = hdr->time;
  1580. X    }
  1581. X    first = 0;
  1582. X    return 1;        /* we read something */
  1583. X}
  1584. X
  1585. VOID
  1586. put_int(number, f)        /* write a 2 byte integer */
  1587. X    short           number;
  1588. X    FILE           *f;
  1589. X{
  1590. X    fputc((char) (number & 255), f);
  1591. X    fputc((char) (number >> 8), f);
  1592. X}
  1593. X
  1594. VOID
  1595. put_long(number, f)        /* write a 4 byte integer */
  1596. X    long            number;
  1597. X    FILE           *f;
  1598. X{
  1599. X    put_int((short) (number & 0xFFFF), f);
  1600. X    put_int((short) (number >> 16), f);
  1601. X}
  1602. X
  1603. VOID
  1604. writehdr(hdr, f)        /* write a header to an archive */
  1605. X    struct heads   *hdr;    /* header to write */
  1606. X    FILE           *f;    /* archive to write to */
  1607. X{
  1608. X    fputc(ARCMARK, f);        /* write out the mark of ARC */
  1609. X    fputc(hdrver, f);    /* write out the header version */
  1610. X    if (!hdrver)        /* if that's the end */
  1611. X        return;        /* then write no more */
  1612. X#if    MSDOS
  1613. X    fwrite(hdr, sizeof(struct heads), 1, f);
  1614. X#else
  1615. X    /* byte/word ordering hassles... */
  1616. X#if    _MTS
  1617. X    etoa(hdr->name, strlen(hdr->name));
  1618. X#endif
  1619. X    fwrite(hdr->name, 1, FNLEN, f);
  1620. X    put_long(hdr->size, f);
  1621. X    put_int(hdr->date, f);
  1622. X    put_int(hdr->time, f);
  1623. X    put_int(hdr->crc, f);
  1624. X    put_long(hdr->length, f);
  1625. X#endif
  1626. X
  1627. X    /* note the newest file for updating the archive timestamp */
  1628. X
  1629. X    if (hdr->date > arcdate
  1630. X        || (hdr->date == arcdate && hdr->time > arctime)) {
  1631. X        arcdate = hdr->date;
  1632. X        arctime = hdr->time;
  1633. X    }
  1634. X}
  1635. X
  1636. char    pinbuf[MYBUF];    /* general purpose input buffer */
  1637. X
  1638. X/*
  1639. X * NOTE:  The filecopy() function is used to move large numbers of bytes from
  1640. X * one file to another.  This particular version has been modified to improve
  1641. X * performance in Computer Innovations C86 version 2.3 in the small memory
  1642. X * model.  It may not work as expected with other compilers or libraries, or
  1643. X * indeed with different versions of the CI-C86 compiler and library, or with
  1644. X * the same version in a different memory model.
  1645. X * 
  1646. X * The following is a functional equivalent to the filecopy() routine that
  1647. X * should work properly on any system using any compiler, albeit at the cost
  1648. X * of reduced performance:
  1649. X * 
  1650. X * filecopy(f,t,size) 
  1651. X *      FILE *f, *t; long size; 
  1652. X * { 
  1653. X *      while(size--)
  1654. X *              putc_tst(fgetc(f),t); 
  1655. X * }
  1656. X */
  1657. X#if    MSDOS
  1658. X#include <fileio2.h>
  1659. X
  1660. filecopy(f, t, size)        /* bulk file copier */
  1661. X    FILE           *f, *t;    /* files from and to */
  1662. X    long            size;    /* bytes to copy */
  1663. X{
  1664. X    unsigned int    bufl;    /* buffer length */
  1665. X    unsigned int    coreleft();    /* space available reporter */
  1666. X    unsigned int    cpy;    /* bytes being copied */
  1667. X    long            floc, tloc, fseek();    /* file pointers, setter */
  1668. X    struct regval   reg;    /* registers for DOS calls */
  1669. X
  1670. X    bufl = (MYBUF > size) ? (u_int) size : MYBUF;
  1671. X
  1672. X    floc = fseek(f, 0L, 1);    /* reset I/O system */
  1673. X    tloc = fseek(t, 0L, 1);
  1674. X
  1675. X    segread(®.si);    /* set segment registers for DOS */
  1676. X
  1677. X    while (size > 0) {    /* while more to copy */
  1678. X        reg.ax = 0x3F00;/* read from handle */
  1679. X        reg.bx = filehand(f);
  1680. X        reg.cx = bufl < size ? bufl : size;    /* amount to read */
  1681. X        reg.dx = pinbuf;
  1682. X        if (sysint21(®, ®) & 1)
  1683. X            arcdie("Read fail");
  1684. X
  1685. X        cpy = reg.ax;    /* amount actually read */
  1686. X        reg.ax = 0x4000;/* write to handle */
  1687. X        reg.bx = filehand(t);
  1688. X        reg.cx = cpy;
  1689. X        reg.dx = pinbuf;
  1690. X        sysint21(®, ®);
  1691. X
  1692. X        if (reg.ax != cpy)
  1693. X            arcdie("Write fail (disk full?)");
  1694. X
  1695. X        size -= (long) cpy;
  1696. X    }
  1697. X}
  1698. X#else
  1699. X
  1700. VOID
  1701. filecopy(f, t, size)        /* bulk file copier */
  1702. X    FILE           *f, *t;    /* files from and to */
  1703. X    long            size;    /* bytes to copy */
  1704. X{
  1705. X    unsigned int    bufl;    /* buffer length */
  1706. X    unsigned int    cpy;    /* bytes being copied */
  1707. X
  1708. X    bufl = (MYBUF > size) ? (u_int) size : MYBUF;
  1709. X
  1710. X    while (size > 0) {
  1711. X        cpy = fread(pinbuf, sizeof(char), bufl, f);
  1712. X        if (fwrite(pinbuf, sizeof(char), cpy, t) != cpy)
  1713. X            arcdie("Write fail (no space?)");
  1714. X        size -= cpy;
  1715. X        if (bufl > size)
  1716. X            bufl = size;
  1717. X        if (ferror(f))
  1718. X            arcdie("Unexpected EOF copying archive");
  1719. X        if (!cpy) break;
  1720. X    }
  1721. X}
  1722. X#endif
  1723. END_OF_FILE
  1724. if test 6860 -ne `wc -c <'arcio.c'`; then
  1725.     echo shar: \"'arcio.c'\" unpacked with wrong size!
  1726. fi
  1727. # end of 'arcio.c'
  1728. fi
  1729. if test -f 'arclst.c' -a "${1}" != "-c" ; then 
  1730.   echo shar: Will not clobber existing file \"'arclst.c'\"
  1731. else
  1732. echo shar: Extracting \"'arclst.c'\" \(4518 characters\)
  1733. sed "s/^X//" >'arclst.c' <<'END_OF_FILE'
  1734. X/*
  1735. X * $Header: /var/local/hyc/src/arc/RCS/arclst.c,v 2.0 1991/11/12 00:30:01 hyc Exp $
  1736. X */
  1737. X
  1738. X/*  ARC - Archive utility - ARCLST
  1739. X  
  1740. X    Version 2.39, created on 04/22/87 at 13:48:29
  1741. X  
  1742. X(C) COPYRIGHT 1985-87 by System Enhancement Associates; ALL RIGHTS RESERVED
  1743. X  
  1744. X    By:     Thom Henderson
  1745. X  
  1746. X    Description:
  1747. X     This file contains the routines used to list the contents
  1748. X     of an archive.
  1749. X  
  1750. X    Language:
  1751. X     Computer Innovations Optimizing C86
  1752. X*/
  1753. X#include <stdio.h>
  1754. X#include "arc.h"
  1755. X
  1756. VOID            rempath(), openarc(), closearc();
  1757. int             readhdr(), match();
  1758. static    VOID    lstfile();
  1759. X
  1760. VOID
  1761. lstarc(num, arg)        /* list files in archive */
  1762. X    int             num;    /* number of arguments */
  1763. X    char           *arg[];    /* pointers to arguments */
  1764. X{
  1765. X    struct heads    hdr;    /* header data */
  1766. X    int             list;    /* true to list a file */
  1767. X    int             did[MAXARG];    /* true when argument was used */
  1768. X    long            tnum, tlen, tsize;    /* totals */
  1769. X    int             n;    /* index */
  1770. X
  1771. X    tnum = tlen = tsize = 0;/* reset totals */
  1772. X
  1773. X    for (n = 0; n < num; n++)    /* for each argument */
  1774. X        did[n] = 0;    /* reset usage flag */
  1775. X    rempath(num, arg);    /* strip off paths */
  1776. X
  1777. X    if (note && !kludge) {
  1778. X        printf("Name          Length  ");
  1779. X        if (bose)
  1780. X            printf("  Stowage    SF   Size now");
  1781. X        printf("  Date     ");
  1782. X        if (bose)
  1783. X            printf("  Time    CRC");
  1784. X        printf("\n");
  1785. X
  1786. X        printf("============  ========");
  1787. X        if (bose)
  1788. X            printf("  ========  ====  ========");
  1789. X        printf("  =========");
  1790. X        if (bose)
  1791. X            printf("  ======  ====");
  1792. X        printf("\n");
  1793. X    }
  1794. X    openarc(0);        /* open archive for reading */
  1795. X
  1796. X    if (num) {        /* if files were named */
  1797. X        while (readhdr(&hdr, arc)) {    /* process all archive files */
  1798. X            list = 0;    /* reset list flag */
  1799. X            for (n = 0; n < num; n++) {    /* for each template
  1800. X                             * given */
  1801. X                if (match(hdr.name, arg[n])) {
  1802. X                    list = 1;    /* turn on list flag */
  1803. X                    did[n] = 1;    /* turn on usage flag */
  1804. X                    break;    /* stop looking */
  1805. X                }
  1806. X            }
  1807. X
  1808. X            if (list) {    /* if this file is wanted */
  1809. X                if (!kludge)
  1810. X                    lstfile(&hdr);    /* then tell about it */
  1811. X                tnum++;    /* update totals */
  1812. X                tlen += hdr.length;
  1813. X                tsize += hdr.size;
  1814. X            }
  1815. X            fseek(arc, hdr.size, 1);    /* move to next header */
  1816. X        }
  1817. X    } else
  1818. X        while (readhdr(&hdr, arc)) {    /* else report on all files */
  1819. X            if (!kludge)
  1820. X                lstfile(&hdr);
  1821. X            tnum++;    /* update totals */
  1822. X            tlen += hdr.length;
  1823. X            tsize += hdr.size;
  1824. X            fseek(arc, hdr.size, 1);    /* skip to next header */
  1825. X        }
  1826. X
  1827. X    closearc(0);        /* close archive after reading */
  1828. X
  1829. X    if (note && !kludge) {
  1830. X        printf("        ====  ========");
  1831. X        if (bose)
  1832. X            printf("            ====  ========");
  1833. X        printf("\n");
  1834. X    }
  1835. X    if (note) {
  1836. X        printf("Total %6ld  %8ld", tnum, tlen);
  1837. X        if (bose) {
  1838. X            if (tlen)
  1839. X                printf("            %3ld%%", 100L - (100L * tsize) / tlen);
  1840. X            else
  1841. X                printf("            ---");
  1842. X            printf("  %8ld", tsize);
  1843. X        }
  1844. X        printf("\n");
  1845. X
  1846. X        for (n = 0; n < num; n++) {    /* report unused args */
  1847. X            if (!did[n]) {
  1848. X                printf("File not found: %s\n", arg[n]);
  1849. X                nerrs++;
  1850. X            }
  1851. X        }
  1852. X    }
  1853. X}
  1854. X
  1855. static    VOID
  1856. lstfile(hdr)            /* tell about a file */
  1857. X    struct heads   *hdr;    /* pointer to header data */
  1858. X{
  1859. X    int             yr, mo, dy;    /* parts of a date */
  1860. X    int             hh, mm;    /* parts of a time */
  1861. X
  1862. X    static char    *mon[] =    /* month abbreviations */
  1863. X    {"???",            /* For month == 0 */
  1864. X     "Jan", "Feb", "Mar", "Apr",
  1865. X     "May", "Jun", "Jul", "Aug",
  1866. X     "Sep", "Oct", "Nov", "Dec"
  1867. X    };
  1868. X
  1869. X    if (!note) {        /* no notes means short listing */
  1870. X        printf("%s\n", hdr->name);
  1871. X        return;
  1872. X    }
  1873. X
  1874. X    yr = (hdr->date >> 9) & 0x7f;    /* dissect the date */
  1875. X    mo = (hdr->date >> 5) & 0x0f;
  1876. X    if (mo > 12)        /* just in case... */
  1877. X        mo = 0;
  1878. X    dy = hdr->date & 0x1f;
  1879. X
  1880. X    hh = (hdr->time >> 11) & 0x1f;    /* dissect the time */
  1881. X    mm = (hdr->time >> 5) & 0x3f;
  1882. X/*    ss = (hdr->time & 0x1f) * 2;    seconds, not used. */
  1883. X
  1884. X    printf("%-12s  %8ld  ", hdr->name, hdr->length);
  1885. X
  1886. X    if (bose) {
  1887. X        switch (hdrver) {
  1888. X        case 1:
  1889. X        case 2:
  1890. X            printf("   --   ");
  1891. X            break;
  1892. X        case 3:
  1893. X            printf(" Packed ");
  1894. X            break;
  1895. X        case 4:
  1896. X            printf("Squeezed");
  1897. X            break;
  1898. X        case 5:
  1899. X        case 6:
  1900. X        case 7:
  1901. X            printf("crunched");
  1902. X            break;
  1903. X        case 8:
  1904. X            printf("Crunched");
  1905. X            break;
  1906. X        case 9:
  1907. X            printf("Squashed");
  1908. X            break;
  1909. X        default:
  1910. X            printf("Unknown!");
  1911. X        }
  1912. X
  1913. X        if (hdr->length)
  1914. X            printf("  %3ld%%", 100L - (100L * hdr->size) / hdr->length);
  1915. X        else
  1916. X            printf("  ---");
  1917. X        printf("  %8ld  ", hdr->size);
  1918. X    }
  1919. X    printf("%2d %3s %02d", dy, mon[mo], (yr + 80) % 100);
  1920. X
  1921. X    if (bose)
  1922. X        printf("  %2d:%02d%c  %04x",
  1923. X               (hh > 12 ? hh - 12 : hh), mm, (hh > 11 ? 'p' : 'a'),
  1924. X               hdr->crc & 0xffff);
  1925. X
  1926. X    printf("\n");
  1927. X}
  1928. END_OF_FILE
  1929. if test 4518 -ne `wc -c <'arclst.c'`; then
  1930.     echo shar: \"'arclst.c'\" unpacked with wrong size!
  1931. fi
  1932. # end of 'arclst.c'
  1933. fi
  1934. if test -f 'arcmatch.c' -a "${1}" != "-c" ; then 
  1935.   echo shar: Will not clobber existing file \"'arcmatch.c'\"
  1936. else
  1937. echo shar: Extracting \"'arcmatch.c'\" \(2999 characters\)
  1938. sed "s/^X//" >'arcmatch.c' <<'END_OF_FILE'
  1939. X/*
  1940. X * $Header: /var/local/hyc/src/arc/RCS/arcmatch.c,v 2.0 1991/11/12 00:30:01 hyc Exp $
  1941. X */
  1942. X
  1943. X/*
  1944. X * ARC - Archive utility - ARCMATCH
  1945. X * 
  1946. X * Version 2.17, created on 12/17/85 at 20:32:18
  1947. X * 
  1948. X * (C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED
  1949. X * 
  1950. X * By:  Thom Henderson
  1951. X * 
  1952. X * Description: This file contains service routines needed to maintain an
  1953. X * archive.
  1954. X * 
  1955. X * Language: Computer Innovations Optimizing C86
  1956. X */
  1957. X#include <stdio.h>
  1958. X#include "arc.h"
  1959. X
  1960. X#include <string.h>
  1961. X#if    BSD
  1962. X#include <strings.h>
  1963. X#endif
  1964. X
  1965. VOID    arcdie();
  1966. X
  1967. int
  1968. match(n, t)            /* test name against template */
  1969. X    char           *n;    /* name to test */
  1970. X    char           *t;    /* template to test against */
  1971. X{
  1972. X#if    _MTS
  1973. X    fortran         patbuild(), patmatch(), patfree();
  1974. X    static int      patlen = (-1);
  1975. X    static int      patwork = 0;
  1976. X    static int      patswch = 0;
  1977. X    char            patccid[4];
  1978. X    static char     patchar[2] = "?";
  1979. X    static char     oldtemp[16] = 0;
  1980. X    int             namlen, RETCODE;
  1981. X
  1982. X    if (strcmp(t, oldtemp)) {
  1983. X        if (patwork)
  1984. X            patfree(&patwork);
  1985. X        strcpy(oldtemp, t);
  1986. X        patlen = strlen(oldtemp);
  1987. X        patbuild(oldtemp, &patlen, &patwork, &patswch, patccid, patchar, _retcode RETCODE);
  1988. X        if (RETCODE > 8) {
  1989. X            printf("MTS: patbuild returned %d\n", RETCODE);
  1990. X            arcdie("bad wildcard in filename");
  1991. X        }
  1992. X    }
  1993. X    namlen = strlen(n);
  1994. X    patmatch(n, &namlen, &patwork, _retcode RETCODE);
  1995. X    switch (RETCODE) {
  1996. X    case 0:
  1997. X        return (1);
  1998. X    case 4:
  1999. X        return (0);
  2000. X    default:
  2001. X        arcdie("wildcard pattern match failed");
  2002. X    }
  2003. X}
  2004. X
  2005. X#else
  2006. X#if    !UNIX
  2007. X    upper(n);
  2008. X    upper(t);        /* avoid case problems */
  2009. X#endif    /* UNIX */
  2010. X
  2011. X    /* first match name part */
  2012. X
  2013. X    while ((*n && *n != '.') || (*t && *t != '.')) {
  2014. X        if (*n != *t && *t != '?') {    /* match fail? */
  2015. X            if (*t != '*')    /* wildcard fail? */
  2016. X                return 0;    /* then no match */
  2017. X            else {    /* else jump over wildcard */
  2018. X                while (*n && *n != '.')
  2019. X                    n++;
  2020. X                while (*t && *t != '.')
  2021. X                    t++;
  2022. X                break;    /* name part matches wildcard */
  2023. X            }
  2024. X        } else {    /* match good for this char */
  2025. X            n++;    /* advance to next char */
  2026. X            t++;
  2027. X        }
  2028. X    }
  2029. X
  2030. X    if (*n && *n == '.')
  2031. X        n++;        /* skip extension delimiters */
  2032. X    if (*t && *t == '.')
  2033. X        t++;
  2034. X
  2035. X    /* now match name part */
  2036. X
  2037. X    while (*n || *t) {
  2038. X        if (*n != *t && *t != '?') {    /* match fail? */
  2039. X            if (*t != '*')    /* wildcard fail? */
  2040. X                return 0;    /* then no match */
  2041. X            else
  2042. X                return 1;    /* else good enough */
  2043. X        } else {    /* match good for this char */
  2044. X            n++;    /* advance to next char */
  2045. X            t++;
  2046. X        }
  2047. X    }
  2048. X
  2049. X    return 1;        /* match worked */
  2050. X}
  2051. X#endif
  2052. X
  2053. VOID
  2054. rempath(nargs, arg)        /* remove paths from filenames */
  2055. X    int             nargs;    /* number of names */
  2056. X    char           *arg[];    /* pointers to names */
  2057. X{
  2058. X    char           *i;    /* string index, reverse indexer */
  2059. X    int             n;    /* index */
  2060. X
  2061. X    for (n = 0; n < nargs; n++) {    /* for each supplied name */
  2062. X        if (!(i = rindex(arg[n], '\\')))    /* search for end of
  2063. X                             * path */
  2064. X            if (!(i = rindex(arg[n], '/')))
  2065. X                i = rindex(arg[n], ':');
  2066. X        if (i)        /* if path was found */
  2067. X            arg[n] = i + 1;    /* then skip it */
  2068. X    }
  2069. X}
  2070. END_OF_FILE
  2071. if test 2999 -ne `wc -c <'arcmatch.c'`; then
  2072.     echo shar: \"'arcmatch.c'\" unpacked with wrong size!
  2073. fi
  2074. # end of 'arcmatch.c'
  2075. fi
  2076. if test -f 'arcpack.c' -a "${1}" != "-c" ; then 
  2077.   echo shar: Will not clobber existing file \"'arcpack.c'\"
  2078. else
  2079. echo shar: Extracting \"'arcpack.c'\" \(6658 characters\)
  2080. sed "s/^X//" >'arcpack.c' <<'END_OF_FILE'
  2081. X/*
  2082. X * $Header: /var/local/hyc/src/arc/RCS/arcpack.c,v 2.0 1991/11/12 00:34:06 hyc Exp $
  2083. X */
  2084. X
  2085. X/*  ARC - Archive utility - ARCPACK
  2086. X
  2087. X    Version 3.49, created on 04/21/87 at 11:26:51
  2088. X
  2089. X(C) COPYRIGHT 1985-87 by System Enhancement Associates; ALL RIGHTS RESERVED
  2090. X
  2091. X    By:     Thom Henderson
  2092. X
  2093. X    Description:
  2094. X     This file contains the routines used to compress a file
  2095. X     when placing it in an archive.
  2096. X
  2097. X    Language:
  2098. X     Computer Innovations Optimizing C86
  2099. X*/
  2100. X#include <stdio.h>
  2101. X#include "arc.h"
  2102. X#if    _MTS
  2103. X#include <ctype.h>
  2104. X#endif
  2105. X
  2106. X#include "proto.h"
  2107. X
  2108. VOID        setcode(), init_cm(), codebuf();
  2109. VOID        arcdie(), init_sq(), flsh_cm();
  2110. int        crcbuf();
  2111. u_int        ncr_buf();
  2112. X
  2113. int        lastc;
  2114. X
  2115. X/* stuff for non-repeat packing */
  2116. X
  2117. X#define DLE 0x90        /* repeat sequence marker */
  2118. X
  2119. u_char    state;        /* current packing state */
  2120. X
  2121. X/* non-repeat packing states */
  2122. X
  2123. X#define NOHIST    0        /* don't consider previous input */
  2124. X#define SENTCHAR 1        /* lastchar set, no lookahead yet */
  2125. X
  2126. extern    u_char    pinbuf[MYBUF];
  2127. u_char        pakbuf[2L*MYBUF];    /* worst case, 2*inbuf */
  2128. X
  2129. X/* packing results */
  2130. X
  2131. long        stdlen;        /* length for standard packing */
  2132. short        crcval;        /* CRC check value */
  2133. X
  2134. VOID
  2135. pack(f, t, hdr)            /* pack file into an archive */
  2136. X    FILE           *f, *t;    /* source, destination */
  2137. X    struct heads   *hdr;    /* pointer to header data */
  2138. X{
  2139. X    long        ncrlen; /* length after packing */
  2140. X    long        huflen; /* length after squeezing */
  2141. X    long        lzwlen; /* length after crunching */
  2142. X    long        pred_sq(), head_sq(), huf_buf();    /* stuff for squeezing */
  2143. X    long        pred_cm();    /* dynamic crunching cleanup */
  2144. X    long        tloc, ftell();    /* start of output */
  2145. X    u_int        inbytes, pakbytes;
  2146. X
  2147. X    /* first pass - see which method is best */
  2148. X
  2149. X    tloc = ftell(t);    /* note start of output */
  2150. X
  2151. X    if (!nocomp) {        /* if storage kludge not active */
  2152. X        if (note) {
  2153. X            printf(" analyzing, ");
  2154. X            fflush(stdout);
  2155. X        }
  2156. X        state = NOHIST; /* initialize ncr packing */
  2157. X        stdlen = ncrlen = 0;    /* reset size counters */
  2158. X        huflen = lzwlen = 0;
  2159. X        crcval = 0;    /* initialize CRC check value */
  2160. X        setcode();    /* initialize encryption */
  2161. X        init_sq();    /* initialize for squeeze scan */
  2162. X
  2163. X        inbytes = getbuf(f);
  2164. X        if (inbytes) {
  2165. X
  2166. X            init_cm(pinbuf);
  2167. X
  2168. X            for (;; inbytes = getbuf(f)) {
  2169. X                pakbytes = ncr_buf(inbytes);
  2170. X                ncrlen += pakbytes;
  2171. X                hufb_tab(pakbuf, pakbytes);
  2172. X                if (dosquash)
  2173. X                    lzw_buf(pinbuf, inbytes, t);
  2174. X                else
  2175. X                    lzw_buf(pakbuf, pakbytes, t);
  2176. X                if (inbytes < MYBUF)
  2177. X                    break;
  2178. X            }
  2179. X            lzwlen = pred_cm(t);
  2180. X            huflen = pred_sq();
  2181. X        }
  2182. X    } else {        /* else kludge the method */
  2183. X        stdlen = 0;    /* make standard look best */
  2184. X        ncrlen = huflen = lzwlen = 1;
  2185. X    }
  2186. X
  2187. X    /* standard set-ups common to all methods */
  2188. X
  2189. X    hdr->crc = crcval;    /* note CRC check value */
  2190. X    hdr->length = stdlen;    /* set actual file length */
  2191. X    if (stdlen > MYBUF) {
  2192. X        fseek(f, 0L, 0);/* rewind input */
  2193. X        state = NOHIST; /* reinitialize ncr packing */
  2194. X        setcode();    /* reinitialize encryption */
  2195. X    } else
  2196. X        inbytes = stdlen;
  2197. X
  2198. X    /* choose and use the shortest method */
  2199. X
  2200. X    if (kludge && note)
  2201. X        printf("\n\tS:%ld  P:%ld  S:%ld     C:%ld,\t ",
  2202. X               stdlen, ncrlen, huflen, lzwlen);
  2203. X
  2204. X    if (stdlen <= ncrlen && stdlen <= huflen && stdlen <= lzwlen) {
  2205. X        if (note) {
  2206. X            printf("storing, ");    /* store without compression */
  2207. X            fflush(stdout);
  2208. X        }
  2209. X        hdrver = 2;    /* note packing method */
  2210. X        fseek(t, tloc, 0);    /* reset output for new method */
  2211. X        if (nocomp || (stdlen > MYBUF)) {
  2212. X            stdlen = crcval = 0;
  2213. X            while ((inbytes = getbuf(f)) != 0)
  2214. X                putb_pak(pinbuf, inbytes, t); /* store it straight */
  2215. X        } else
  2216. X            putb_pak(pinbuf, inbytes, t);
  2217. X        hdr->crc = crcval;
  2218. X        hdr->length = hdr->size = stdlen;
  2219. X    } else if (ncrlen < lzwlen && ncrlen < huflen) {
  2220. X        if (note) {
  2221. X            printf("packing, ");    /* pack with repeat */
  2222. X            fflush(stdout); /* suppression */
  2223. X        }
  2224. X        hdrver = 3;    /* note packing method */
  2225. X        hdr->size = ncrlen;    /* set data length */
  2226. X        fseek(t, tloc, 0);    /* reset output for new method */
  2227. X        if (stdlen > MYBUF) {
  2228. X            do {
  2229. X                inbytes = getbuf(f);
  2230. X                pakbytes = ncr_buf(inbytes);
  2231. X                putb_pak(pakbuf, pakbytes, t);
  2232. X            } while (inbytes != 0);
  2233. X        } else
  2234. X            putb_pak(pakbuf, pakbytes, t);
  2235. X    } else if (huflen < lzwlen) {
  2236. X        if (note) {
  2237. X            printf("squeezing, ");
  2238. X            fflush(stdout);
  2239. X        }
  2240. X        hdrver = 4;    /* note packing method */
  2241. X        fseek(t, tloc, 0);    /* reset output for new method */
  2242. X        huflen = head_sq();
  2243. X        if (stdlen > MYBUF) {
  2244. X            do {
  2245. X                inbytes = getbuf(f);
  2246. X                pakbytes = ncr_buf(inbytes);
  2247. X                huflen += huf_buf(pakbuf, pakbytes, inbytes, t);
  2248. X            } while (inbytes != 0);
  2249. X        } else
  2250. X            huflen += huf_buf(pakbuf, pakbytes, 0, t);
  2251. X
  2252. X        hdr->size = huflen;    /* note final size */
  2253. X    } else {
  2254. X        if (note)
  2255. X            printf(dosquash ? "squashed, " : "crunched, ");
  2256. X        flsh_cm(t);
  2257. X        hdrver = dosquash ? 9 : 8;
  2258. X        hdr->size = lzwlen;    /* size should not change */
  2259. X    }
  2260. X
  2261. X    /* standard cleanups common to all methods */
  2262. X
  2263. X    if (note)
  2264. X        printf("done. (%ld%%)\n", hdr->length == 0 ?
  2265. X               0L : 100L - (100L * hdr->size) / hdr->length);
  2266. X}
  2267. X
  2268. X/*
  2269. X * Non-repeat compression - text is passed through normally, except that a
  2270. X * run of more than two is encoded as:
  2271. X *
  2272. X * <char> <DLE> <count>
  2273. X *
  2274. X * Special case: a count of zero indicates that the DLE is really a DLE, not a
  2275. X * repeat marker.
  2276. X */
  2277. X
  2278. u_int
  2279. ncr_buf(inbytes)
  2280. X    u_int        inbytes;    /* number of bytes in inbuf */
  2281. X{
  2282. X    u_int        i;
  2283. X    int        c;
  2284. X    reg u_char     *inptr, *pakptr;
  2285. X    static int    cnt;
  2286. X
  2287. X    inptr = pinbuf;
  2288. X    pakptr = pakbuf;
  2289. X
  2290. X    if (state == NOHIST) {
  2291. X        lastc = (-1);
  2292. X        cnt = 1;
  2293. X        state = SENTCHAR;
  2294. X    }
  2295. X    for (i = 0; i < inbytes; i++) {
  2296. X        c = *inptr++;
  2297. X        if (c == lastc && cnt < 255)
  2298. X            cnt++;
  2299. X        else {
  2300. X            if (cnt == 2) {
  2301. X                *pakptr++ = lastc;
  2302. X            } else if (cnt > 2) {
  2303. X                *pakptr++ = DLE;
  2304. X                *pakptr++ = cnt;
  2305. X            }
  2306. X            *pakptr++ = c;
  2307. X            lastc = c;
  2308. X            cnt = 1;
  2309. X        }
  2310. X        if (c == DLE) {
  2311. X            *pakptr++ = '\0';
  2312. X            lastc = (-1);
  2313. X        }
  2314. X    }
  2315. X    if (inbytes < MYBUF && cnt > 1) {    /* trailing stuff */
  2316. X        if (cnt == 2)
  2317. X            *pakptr++ = lastc;
  2318. X        else {
  2319. X            *pakptr++ = DLE;
  2320. X            *pakptr++ = cnt;
  2321. X        }
  2322. X    }
  2323. X    return (pakptr - pakbuf);
  2324. X}
  2325. X
  2326. u_int
  2327. getbuf(f)
  2328. X    FILE           *f;
  2329. X{
  2330. X    u_int        i;
  2331. X#if    !DOS
  2332. X    int        c;
  2333. X    static int    cr = 0;
  2334. X    register u_char *ptr;
  2335. X    if (image) {
  2336. X#endif
  2337. X        i = fread(pinbuf, 1, MYBUF, f);
  2338. X#if    !DOS
  2339. X    } else {
  2340. X        ptr = pinbuf;
  2341. X        for (i = 0, c = 0; (c != EOF) && (i < MYBUF); i++) {
  2342. X            if (cr) {
  2343. X                c = '\n';
  2344. X                cr = 0;
  2345. X            } else {
  2346. X                c = fgetc(f);
  2347. X                if (c == EOF)
  2348. X                    break;
  2349. X                else if (c == '\n') {
  2350. X                    c = '\r';
  2351. X                    cr = 1;
  2352. X                }
  2353. X            }
  2354. X            *ptr++ = c;
  2355. X        }
  2356. X#if    _MTS
  2357. X        etoa(pinbuf, i);
  2358. X#endif                /* _MTS */
  2359. X    }
  2360. X#endif                /* !DOS */
  2361. X    crcval = crcbuf(crcval, i, pinbuf);
  2362. X    stdlen += i;
  2363. X    return (i);
  2364. X}
  2365. X
  2366. VOID
  2367. putb_pak(buf, len, f)
  2368. X    u_char           *buf;
  2369. X    u_int        len;
  2370. X    FILE           *f;
  2371. X{
  2372. X    u_int        i;
  2373. X
  2374. X    if (f && len) {
  2375. X        if (password)
  2376. X            codebuf(buf, len);
  2377. X        i = fwrite(buf, 1, len, f);
  2378. X        if (i != len)
  2379. X            arcdie("Write failed");
  2380. X    }
  2381. X}
  2382. END_OF_FILE
  2383. if test 6658 -ne `wc -c <'arcpack.c'`; then
  2384.     echo shar: \"'arcpack.c'\" unpacked with wrong size!
  2385. fi
  2386. # end of 'arcpack.c'
  2387. fi
  2388. if test -f 'arcrun.c' -a "${1}" != "-c" ; then 
  2389.   echo shar: Will not clobber existing file \"'arcrun.c'\"
  2390. else
  2391. echo shar: Extracting \"'arcrun.c'\" \(3891 characters\)
  2392. sed "s/^X//" >'arcrun.c' <<'END_OF_FILE'
  2393. X/*
  2394. X * $Header: /var/local/hyc/src/arc/RCS/arcrun.c,v 2.0 1991/11/12 00:30:01 hyc Exp $
  2395. X */
  2396. X
  2397. X/*
  2398. X * ARC - Archive utility - ARCRUN
  2399. X * 
  2400. X * Version 1.20, created on 03/24/86 at 19:34:31
  2401. X * 
  2402. X * (C) COPYRIGHT 1985,85 by System Enhancement Associates; ALL RIGHTS RESERVED
  2403. X * 
  2404. X * By:  Thom Henderson
  2405. X * 
  2406. X * Description: This file contains the routines used to "run" a file which is
  2407. X * stored in an archive.  At present, all we really do is (a) extract a
  2408. X * temporary file, (b) give its name as a system command, and then (c) delete
  2409. X * the file.
  2410. X * 
  2411. X * Language: Computer Innovations Optimizing C86
  2412. X */
  2413. X#include <stdio.h>
  2414. X#include "arc.h"
  2415. X
  2416. VOID    rempath(), openarc(), closearc(), arcdie();
  2417. int    readhdr(), match(), unpack();
  2418. static    VOID    runfile();
  2419. char    *strcat();
  2420. X
  2421. VOID
  2422. runarc(num, arg)        /* run file from archive */
  2423. X    int             num;    /* number of arguments */
  2424. X    char           *arg[];    /* pointers to arguments */
  2425. X{
  2426. X    struct heads    hdr;    /* file header */
  2427. X    char           *makefnam();    /* filename fixer */
  2428. X    char            buf[STRLEN];    /* filename buffer */
  2429. X    FILE           *fopen();/* file opener */
  2430. X    char           *dummy[2];
  2431. X
  2432. X    dummy[0]="dummy";
  2433. X    dummy[1]=NULL;
  2434. X    rempath(num, arg);    /* strip off paths */
  2435. X
  2436. X    openarc(0);        /* open archive for reading */
  2437. X
  2438. X    if (num) {        /* if files were named */
  2439. X        while (readhdr(&hdr, arc)) {    /* while more files to check */
  2440. X            if (match(hdr.name, makefnam(arg[0], ".*", buf)))
  2441. X                runfile(&hdr, num, arg);
  2442. X            else
  2443. X                fseek(arc, hdr.size, 1);
  2444. X        }
  2445. X    } else
  2446. X        while (readhdr(&hdr, arc))    /* else run all files */
  2447. X            runfile(&hdr, 1, dummy);
  2448. X
  2449. X    closearc(0);        /* close archive after changes */
  2450. X}
  2451. X
  2452. static  VOID
  2453. runfile(hdr, num, arg)        /* run a file */
  2454. X    struct heads   *hdr;    /* pointer to header data */
  2455. X    int             num;    /* number of arguments */
  2456. X    char           *arg[];    /* pointers to arguments */
  2457. X{
  2458. X    FILE           *tmp, *fopen();    /* temporary file */
  2459. X    char           *dir, *gcdir();    /* directory stuff */
  2460. X    char            buf[STRLEN], *makefnam();    /* temp file name, fixer */
  2461. X#if    DOS
  2462. X    char        nbuf[64], *i, *rindex();
  2463. X#endif
  2464. X#if    !GEMDOS
  2465. X    int             n;    /* index */
  2466. X    char            sys[STRLEN];    /* invocation command buffer */
  2467. X#endif
  2468. X
  2469. X    /* makefnam("$ARCTEMP",hdr->name,buf); */
  2470. X#if    UNIX
  2471. X    sprintf(buf, "%s.RUN", arctemp);
  2472. X    strcpy(sys, buf);
  2473. X#else
  2474. X    strcpy(nbuf, arctemp);
  2475. X    makefnam(nbuf,hdr->name,buf);
  2476. X    i = rindex(buf,'.');
  2477. X#endif
  2478. X#if    MSDOS
  2479. X    if (!strcmp(i, ".BAS")) {
  2480. X        strcpy(sys, "BASICA ");
  2481. X        strcat(sys, buf);
  2482. X    }
  2483. X    else if (!strcmp(i, ".BAT")
  2484. X         || !strcmp(i, ".COM")
  2485. X         || !strcmp(i, ".EXE"))
  2486. X        strcpy(sys, buf);
  2487. X
  2488. X    else {
  2489. X        if (warn) {
  2490. X            printf("File %s is not a .BAS, .BAT, .COM, or .EXE\n",
  2491. X                   hdr->name);
  2492. X            nerrs++;
  2493. X        }
  2494. X        fseek(arc, hdr->size, 1);    /* skip this file */
  2495. X        return;
  2496. X    }
  2497. X#endif
  2498. X#if    GEMDOS
  2499. X      if (strcmp(i, ".PRG")
  2500. X              && strcmp(i, ".TTP")
  2501. X              && strcmp(i, ".TOS"))
  2502. X      {
  2503. X              if (warn) {
  2504. X                      printf("File %s is not a .PRG, .TOS, or .TTP\n",
  2505. X                              hdr->name);
  2506. X                      nerrs++;
  2507. X              }
  2508. X              fseek(arc, hdr->size, 1);       /* skip this file */
  2509. X              return;
  2510. X      }
  2511. X#endif
  2512. X
  2513. X    if (warn)
  2514. X        if (tmp = fopen(buf, "r"))
  2515. X            arcdie("Temporary file %s already exists", buf);
  2516. X    if (!(tmp = fopen(buf, OPEN_W)))
  2517. X        arcdie("Unable to create temporary file %s", buf);
  2518. X
  2519. X    if (note)
  2520. X        printf("Invoking file: %s\n", hdr->name);
  2521. X
  2522. X    dir = gcdir("");    /* see where we are */
  2523. X    unpack(arc, tmp, hdr);    /* unpack the entry */
  2524. X    fclose(tmp);        /* release the file */
  2525. X    chmod(buf, "700");    /* make it executable */
  2526. X#if    GEMDOS
  2527. X    execve(buf, arg, NULL);
  2528. X#else
  2529. X    for (n = 1; n < num; n++) {    /* add command line arguments */
  2530. X        strcat(sys, " ");
  2531. X        strcat(sys, arg[n]);
  2532. X    }
  2533. X    system(buf);        /* try to invoke it */
  2534. X#endif
  2535. X    chdir(dir);
  2536. X    free(dir);        /* return to whence we started */
  2537. X    if (unlink(buf) && warn) {
  2538. X        printf("Cannot unsave temporary file %s\n", buf);
  2539. X        nerrs++;
  2540. X    }
  2541. X}
  2542. END_OF_FILE
  2543. if test 3891 -ne `wc -c <'arcrun.c'`; then
  2544.     echo shar: \"'arcrun.c'\" unpacked with wrong size!
  2545. fi
  2546. # end of 'arcrun.c'
  2547. fi
  2548. if test -f 'arcs.h' -a "${1}" != "-c" ; then 
  2549.   echo shar: Will not clobber existing file \"'arcs.h'\"
  2550. else
  2551. echo shar: Extracting \"'arcs.h'\" \(1674 characters\)
  2552. sed "s/^X//" >'arcs.h' <<'END_OF_FILE'
  2553. X/*
  2554. X * $Header: /var/local/hyc/src/arc/RCS/arcs.h,v 2.0 1991/11/12 00:30:01 hyc Exp $
  2555. X */
  2556. X
  2557. X/*
  2558. X * ARC - Archive utility - Archive file header format
  2559. X * 
  2560. X * Version 2.12, created on 12/17/85 at 14:40:26
  2561. X * 
  2562. X * (C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED
  2563. X * 
  2564. X * By:  Thom Henderson
  2565. X * 
  2566. X * Description: This file defines the format of an archive file header,
  2567. X * excluding the archive marker and the header version number.
  2568. X * 
  2569. X * Each entry in an archive begins with a one byte archive marker, which is set
  2570. X * to 26.  The marker is followed by a one byte header type code, from zero
  2571. X * to 7.
  2572. X * 
  2573. X * If the header type code is zero, then it is an end marker, and no more data
  2574. X * should be read from the archive.
  2575. X * 
  2576. X * If the header type code is in the range 2 to 7, then it is followed by a
  2577. X * standard archive header, which is defined below.
  2578. X * 
  2579. X * If the header type code is one, then it is followed by an older format
  2580. X * archive header.  The older format header does not contain the true length.
  2581. X * A header should be read for a length of sizeof(struct heads)-sizeof(long).
  2582. X * Then set length equal to size and change the header version to 2.
  2583. X * 
  2584. X * Programming note: The crc value given in the header is based on the unpacked
  2585. X * data.
  2586. X * 
  2587. X * Language: Computer Innovations Optimizing C86
  2588. X */
  2589. X
  2590. struct heads {            /* archive entry header format */
  2591. X    char    name[FNLEN];        /* file name */
  2592. X            long size;        /* size of file, in bytes */
  2593. X    unsigned    short date;    /* creation date */
  2594. X    unsigned    short time;    /* creation time */
  2595. X                short crc;    /* cyclic redundancy check */
  2596. X                long length;    /* true file length */
  2597. X};
  2598. END_OF_FILE
  2599. if test 1674 -ne `wc -c <'arcs.h'`; then
  2600.     echo shar: \"'arcs.h'\" unpacked with wrong size!
  2601. fi
  2602. # end of 'arcs.h'
  2603. fi
  2604. if test -f 'arcsvc.c' -a "${1}" != "-c" ; then 
  2605.   echo shar: Will not clobber existing file \"'arcsvc.c'\"
  2606. else
  2607. echo shar: Extracting \"'arcsvc.c'\" \(5488 characters\)
  2608. sed "s/^X//" >'arcsvc.c' <<'END_OF_FILE'
  2609. X/*
  2610. X * $Header: /var/local/hyc/src/arc/RCS/arcsvc.c,v 2.0 1991/11/12 00:30:01 hyc Exp $
  2611. X */
  2612. X
  2613. X/*  ARC - Archive utility - ARCSVC
  2614. X
  2615. X    Version 2.23, created on 04/22/87 at 13:10:10
  2616. X
  2617. X(C) COPYRIGHT 1985-87 by System Enhancement Associates; ALL RIGHTS RESERVED
  2618. X
  2619. X    By:     Thom Henderson
  2620. X
  2621. X    Description:
  2622. X     This file contains service routines needed to maintain an archive.
  2623. X
  2624. X    Language:
  2625. X     Computer Innovations Optimizing C86
  2626. X*/
  2627. X#include <stdio.h>
  2628. X#include "arc.h"
  2629. X#if    _MTS
  2630. X#include <mts.h>
  2631. X#endif
  2632. X
  2633. VOID    arcdie(), setstamp();
  2634. int    unlink();
  2635. X
  2636. VOID
  2637. openarc(chg)            /* open archive */
  2638. X    int             chg;    /* true to open for changes */
  2639. X{
  2640. X    FILE           *fopen();/* file opener */
  2641. X
  2642. X    if (!(arc = fopen(arcname, OPEN_R))) {
  2643. X        if (chg) {
  2644. X            if (note)
  2645. X                printf("Creating new archive: %s\n", arcname);
  2646. X        }
  2647. X        else
  2648. X            arcdie("Archive not found: %s", arcname);
  2649. X    }
  2650. X#if    _MTS    /* allow reading archives of max MTS record length */
  2651. X    {
  2652. X        char *buf, *malloc();
  2653. X        int inlen;
  2654. X        struct GDDSECT *region;
  2655. X
  2656. X        region=gdinfo(arc->_fd._fdub);
  2657. X        inlen=region->GDINLEN;
  2658. X        buf=malloc(inlen);
  2659. X        setbuffer(arc, buf, inlen);
  2660. X    }
  2661. X#endif
  2662. X    if (chg) {        /* if opening for changes */
  2663. X        if (!(new = fopen(newname, OPEN_W)))
  2664. X            arcdie("Cannot create archive copy: %s", newname);
  2665. X
  2666. X    changing = chg;        /* note if open for changes */
  2667. X    }
  2668. X}
  2669. X
  2670. VOID
  2671. closearc(chg)            /* close an archive */
  2672. X    int             chg;    /* true if archive was changed */
  2673. X{
  2674. X    if (arc) {        /* if we had an initial archive */
  2675. X        fclose(arc);
  2676. X#if    !_MTS
  2677. X        if (kludge)    /* kludge to update timestamp */
  2678. X            setstamp(arcname, olddate, oldtime);
  2679. X#endif
  2680. X    }
  2681. X    if (chg) {        /* if things have changed */
  2682. X        fclose(new);    /* close the new copy */
  2683. X        if (arc) {    /* if we had an original archive */
  2684. X#if      _MTS
  2685. X                                {
  2686. X                                 fortran VOID permit();
  2687. X                                 char what[FNLEN+2];
  2688. X/* copy permissions  */          char who[FNLEN+6];
  2689. X/* of old archive to */          int how,whotyp,wholen,info;
  2690. X/* new copy...       */          strcpy(what, newname);
  2691. X                                 strcat(what," ");
  2692. X                                 whotyp=9;
  2693. X                                 sprintf(who,"like %s",arcname);
  2694. X                                 wholen=strlen(who);
  2695. X                                 info=0;
  2696. X                                 permit(what,&how,&whotyp,&wholen,who,&info);
  2697. X                                }
  2698. X#endif
  2699. X            if (keepbak) {    /* if a backup is wanted */
  2700. X                unlink(bakname);    /* erase any old copies */
  2701. X                if (move(arcname, bakname))
  2702. X                    arcdie("Cannot rename %s to %s", arcname, bakname);
  2703. X                printf("Keeping backup archive: %s\n", bakname);
  2704. X            } else if (unlink(arcname))
  2705. X                arcdie("Cannot delete old archive: %s", arcname);
  2706. X        }
  2707. X        if (move(newname, arcname))
  2708. X            arcdie("Cannot move %s to %s", newname, arcname);
  2709. X#if    !_MTS
  2710. X        setstamp(arcname, arcdate, arctime);
  2711. X#endif
  2712. X    }
  2713. X}
  2714. X
  2715. X/*
  2716. X * CRC computation logic
  2717. X * 
  2718. X * The logic for this method of calculating the CRC 16 bit polynomial is taken
  2719. X * from an article by David Schwaderer in the April 1985 issue of PC Tech
  2720. X * Journal.
  2721. X */
  2722. X
  2723. static short      crctab[] =    /* CRC lookup table */
  2724. X{
  2725. X 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
  2726. X 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
  2727. X 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
  2728. X 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
  2729. X 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
  2730. X 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
  2731. X 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
  2732. X 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
  2733. X 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
  2734. X 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
  2735. X 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
  2736. X 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
  2737. X 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
  2738. X 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
  2739. X 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
  2740. X 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
  2741. X 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
  2742. X 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
  2743. X 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
  2744. X 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
  2745. X 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
  2746. X 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
  2747. X 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
  2748. X 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
  2749. X 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
  2750. X 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
  2751. X 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
  2752. X 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
  2753. X 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
  2754. X 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
  2755. X 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
  2756. X 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
  2757. X};
  2758. X
  2759. X/*
  2760. X * Update a CRC check on the given buffer.
  2761. X */
  2762. X
  2763. int
  2764. crcbuf(crc, len, buf)
  2765. X    register int    crc;    /* running CRC value */
  2766. X    register u_int    len;
  2767. X    register u_char    *buf;
  2768. X{
  2769. X    register u_int    i;
  2770. X
  2771. X    for (i=0; i<len; i++)
  2772. X        crc = ((crc >> 8) & 0xff) ^ crctab[(crc ^ *buf++) & 0xff];
  2773. X    
  2774. X    return (crc);
  2775. X}
  2776. END_OF_FILE
  2777. if test 5488 -ne `wc -c <'arcsvc.c'`; then
  2778.     echo shar: \"'arcsvc.c'\" unpacked with wrong size!
  2779. fi
  2780. # end of 'arcsvc.c'
  2781. fi
  2782. if test -f 'arctst.c' -a "${1}" != "-c" ; then 
  2783.   echo shar: Will not clobber existing file \"'arctst.c'\"
  2784. else
  2785. echo shar: Extracting \"'arctst.c'\" \(1313 characters\)
  2786. sed "s/^X//" >'arctst.c' <<'END_OF_FILE'
  2787. X/*
  2788. X * $Header: /var/local/hyc/src/arc/RCS/arctst.c,v 2.0 1991/11/12 00:30:01 hyc Exp $
  2789. X */
  2790. X
  2791. X/*
  2792. X * ARC - Archive utility - ARCTST
  2793. X * 
  2794. X * Version 2.12, created on 02/03/86 at 23:00:40
  2795. X * 
  2796. X * (C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED
  2797. X * 
  2798. X * By:  Thom Henderson
  2799. X * 
  2800. X * Description: This file contains the routines used to test archive integrity.
  2801. X * 
  2802. X * Language: Computer Innovations Optimizing C86
  2803. X */
  2804. X#include <stdio.h>
  2805. X#include "arc.h"
  2806. X
  2807. VOID    openarc();
  2808. int    readhdr(), unpack();
  2809. X
  2810. VOID
  2811. tstarc()
  2812. X{                /* test integrity of an archive */
  2813. X    struct heads    hdr;    /* file header */
  2814. X    long            arcsize, ftell();    /* archive size */
  2815. X
  2816. X    openarc(0);        /* open archive for reading */
  2817. X    fseek(arc, 0L, 2);    /* move to end of archive */
  2818. X    arcsize = ftell(arc);    /* see how big it is */
  2819. X    fseek(arc, 0L, 0);    /* return to top of archive */
  2820. X
  2821. X    while (readhdr(&hdr, arc)) {
  2822. X        if (ftell(arc) + hdr.size > arcsize) {
  2823. X            printf("Archive truncated in file %s\n", hdr.name);
  2824. X            nerrs++;
  2825. X            break;
  2826. X        } else {
  2827. X            printf("Testing file: %-12s  ", hdr.name);
  2828. X            fflush(stdout);
  2829. X            if (unpack(arc, NULL, &hdr))
  2830. X                nerrs++;
  2831. X            else
  2832. X                printf("okay\n");
  2833. X        }
  2834. X    }
  2835. X
  2836. X    if (nerrs < 1)
  2837. X        printf("No errors detected\n");
  2838. X    else if (nerrs == 1)
  2839. X        printf("One error detected\n");
  2840. X    else
  2841. X        printf("%d errors detected\n", nerrs);
  2842. X}
  2843. END_OF_FILE
  2844. if test 1313 -ne `wc -c <'arctst.c'`; then
  2845.     echo shar: \"'arctst.c'\" unpacked with wrong size!
  2846. fi
  2847. # end of 'arctst.c'
  2848. fi
  2849. if test -f 'arcunp.c' -a "${1}" != "-c" ; then 
  2850.   echo shar: Will not clobber existing file \"'arcunp.c'\"
  2851. else
  2852. echo shar: Extracting \"'arcunp.c'\" \(5073 characters\)
  2853. sed "s/^X//" >'arcunp.c' <<'END_OF_FILE'
  2854. X/*
  2855. X * $Header: /var/local/hyc/src/arc/RCS/arcunp.c,v 2.0 1991/11/12 00:30:01 hyc Exp $
  2856. X */
  2857. X
  2858. X/*
  2859. X * ARC - Archive utility - ARCUNP
  2860. X * 
  2861. X * Version 3.17, created on 02/13/86 at 10:20:08
  2862. X * 
  2863. X * (C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED
  2864. X * 
  2865. X * By:  Thom Henderson
  2866. X * 
  2867. X * Description: This file contains the routines used to expand a file when
  2868. X * taking it out of an archive.
  2869. X * 
  2870. X * Language: Computer Innovations Optimizing C86
  2871. X */
  2872. X#include <stdio.h>
  2873. X#include "arc.h"
  2874. X#if    _MTS
  2875. X#include <mts.h>
  2876. X#endif
  2877. X
  2878. VOID    setcode(), init_usq(), init_ucr(), decomp();
  2879. VOID    arcdie(), codebuf();
  2880. X
  2881. X#include "proto.h"
  2882. X
  2883. X/* stuff for repeat unpacking */
  2884. X
  2885. X#define DLE 0x90        /* repeat byte flag */
  2886. X
  2887. extern u_char   state;        /* repeat unpacking state */
  2888. extern int    lastc;
  2889. X
  2890. X/* repeat unpacking states */
  2891. X
  2892. X#define NOHIST 0        /* no relevant history */
  2893. X#define INREP 1            /* sending a repeated value */
  2894. X
  2895. short    crcval;        /* CRC check value */
  2896. long     stdlen;        /* bytes to read */
  2897. X#if    !DOS
  2898. static int    gotcr;        /* got a carriage return? */
  2899. X#endif
  2900. X
  2901. extern u_char    pinbuf[MYBUF], pakbuf[2L*MYBUF];
  2902. extern u_char    outbuf[MYBUF];
  2903. X
  2904. int
  2905. unpack(f, t, hdr)        /* unpack an archive entry */
  2906. X    FILE           *f, *t;    /* source, destination */
  2907. X    struct heads   *hdr;    /* pointer to file header data */
  2908. X{
  2909. X    u_int        len;
  2910. X
  2911. X    /* setups common to all methods */
  2912. X#if    !DOS
  2913. X    gotcr = 0;
  2914. X#endif
  2915. X    crcval = 0;        /* reset CRC check value */
  2916. X    stdlen = hdr->size;    /* set input byte counter */
  2917. X    state = NOHIST;        /* initial repeat unpacking state */
  2918. X    setcode();        /* set up for decoding */
  2919. X
  2920. X    /* use whatever method is appropriate */
  2921. X
  2922. X    switch (hdrver) {    /* choose proper unpack method */
  2923. X    case 1:        /* standard packing */
  2924. X    case 2:
  2925. X        do {
  2926. X            len = getb_unp(f);
  2927. X            putb_unp(pinbuf, len, t);
  2928. X        } while (len == MYBUF);
  2929. X        break;
  2930. X
  2931. X    case 3:        /* non-repeat packing */
  2932. X        do {
  2933. X            len = getb_unp(f);
  2934. X            putb_ncr(pinbuf, len, t);
  2935. X        } while (len == MYBUF);
  2936. X        break;
  2937. X
  2938. X    case 4:        /* Huffman squeezing */
  2939. X        init_usq(f);
  2940. X        do {
  2941. X            len = getb_usq(f);
  2942. X            putb_ncr(outbuf, len, t);
  2943. X        } while (len == MYBUF);
  2944. X        break;
  2945. X
  2946. X    case 5:        /* Lempel-Zev compression */
  2947. X        init_ucr(0, f);
  2948. X        do {
  2949. X            len = getb_ucr(f);
  2950. X            putb_unp(outbuf, len, t);
  2951. X        } while (len == MYBUF);
  2952. X        break;
  2953. X
  2954. X    case 6:        /* Lempel-Zev plus non-repeat */
  2955. X        init_ucr(0, f);
  2956. X        do {
  2957. X            len = getb_ucr(f);
  2958. X            putb_ncr(outbuf, len, t);
  2959. X        } while (len == MYBUF);
  2960. X        break;
  2961. X
  2962. X    case 7:        /* L-Z plus ncr with new hash */
  2963. X        init_ucr(1, f);
  2964. X        do {
  2965. X            len = getb_ucr(f);
  2966. X            putb_ncr(outbuf, len, t);
  2967. X        } while (len == MYBUF);
  2968. X        break;
  2969. X
  2970. X    case 8:        /* dynamic Lempel-Zev */
  2971. X        decomp(0, f, t);
  2972. X        break;
  2973. X
  2974. X    case 9:        /* Squashing */
  2975. X        decomp(1, f, t);
  2976. X        break;
  2977. X
  2978. X    default:        /* unknown method */
  2979. X        if (warn) {
  2980. X            printf("I don't know how to unpack file %s\n", hdr->name);
  2981. X            printf("I think you need a newer version of ARC\n");
  2982. X            nerrs++;
  2983. X        }
  2984. X        fseek(f, hdr->size, 1);    /* skip over bad file */
  2985. X        return 1;    /* note defective file */
  2986. X    }
  2987. X
  2988. X    /* cleanups common to all methods */
  2989. X
  2990. X    if (crcval != hdr->crc) {
  2991. X        if (warn || kludge) {
  2992. X            printf("WARNING: File %s fails CRC check\n", hdr->name);
  2993. X            nerrs++;
  2994. X        }
  2995. X        return 1;    /* note defective file */
  2996. X    }
  2997. X    return 0;        /* file is okay */
  2998. X}
  2999. X
  3000. X/*
  3001. X * This routine is used to put bytes in the output file.  It also performs
  3002. X * various housekeeping functions, such as maintaining the CRC check value.
  3003. X */
  3004. X
  3005. VOID
  3006. putb_unp(buf, len, t)
  3007. X    u_char    *buf;
  3008. X    u_int    len;
  3009. X    FILE    *t;
  3010. X{
  3011. X    u_int i, j;
  3012. X
  3013. X    crcval = crcbuf(crcval, len, buf);
  3014. X
  3015. X    if (!t)
  3016. X        return;
  3017. X#if    !DOS
  3018. X    if (!image) {
  3019. X#if    _MTS
  3020. X        atoe(buf, len);
  3021. X#endif
  3022. X        if (gotcr) {
  3023. X            gotcr = 0;
  3024. X            if (buf[0] != '\n')
  3025. X                putc('\r', t);
  3026. X        }
  3027. X
  3028. X        for (i=0,j=0; i<len; i++)
  3029. X            if (buf[i] != '\r' || buf[i+1] != '\n')
  3030. X                buf[j++] = buf[i];
  3031. X        len = j;
  3032. X
  3033. X        if (buf[len-1] == '\r') {
  3034. X            len--;
  3035. X            gotcr = 1;
  3036. X        }
  3037. X    }
  3038. X#endif    /* !DOS */
  3039. X    i=fwrite(buf, 1, len, t);
  3040. X    if (i != len)
  3041. X        arcdie("Write fail");
  3042. X}
  3043. X
  3044. X/*
  3045. X * This routine is used to decode non-repeat compression.  Bytes are passed
  3046. X * one at a time in coded format, and are written out uncoded. The data is
  3047. X * stored normally, except that runs of more than two characters are
  3048. X * represented as:
  3049. X * 
  3050. X * <char> <DLE> <count>
  3051. X * 
  3052. X * With a special case that a count of zero indicates a DLE as data, not as a
  3053. X * repeat marker.
  3054. X */
  3055. X
  3056. VOID
  3057. putb_ncr(buf, len, t)        /* put NCR coded bytes */
  3058. X    u_char    *buf;
  3059. X    u_int    len;
  3060. X    FILE    *t;        /* file to receive data */
  3061. X{
  3062. X    u_char    *pakptr=pakbuf;
  3063. X    u_int    i;
  3064. X
  3065. X    for (i=0; i<len; i++) {
  3066. X        if (state == INREP) {
  3067. X            if (buf[i])
  3068. X                while (--buf[i])
  3069. X                    *pakptr++ = lastc;
  3070. X            else
  3071. X                *pakptr++ = DLE;
  3072. X            state = NOHIST;
  3073. X        } else {
  3074. X            if (buf[i] != DLE)
  3075. X                *pakptr++ = lastc = buf[i];
  3076. X            else
  3077. X                state = INREP;
  3078. X        }
  3079. X
  3080. X        if (pakptr - pakbuf > MYBUF) {
  3081. X            putb_unp(pakbuf, (u_int) (pakptr-pakbuf), t);
  3082. X            pakptr = pakbuf;
  3083. X        }
  3084. X    }
  3085. X    putb_unp(pakbuf, (u_int) (pakptr-pakbuf), t);
  3086. X}
  3087. X
  3088. X/*
  3089. X * This routine reads a buffer of data from an archive.
  3090. X */
  3091. X
  3092. u_int
  3093. getb_unp(f)
  3094. X    FILE        *f;
  3095. X{
  3096. X    register u_int len;
  3097. X
  3098. X    if (stdlen) {
  3099. X        len = (stdlen < MYBUF) ? stdlen : MYBUF;
  3100. X
  3101. X        len = fread(pinbuf, 1, len, f);
  3102. X
  3103. X        if (password)
  3104. X            codebuf(pinbuf, len);
  3105. X    
  3106. X        stdlen -= len;
  3107. X    } else
  3108. X        len = 0;
  3109. X    
  3110. X    return (len);
  3111. X}
  3112. END_OF_FILE
  3113. if test 5073 -ne `wc -c <'arcunp.c'`; then
  3114.     echo shar: \"'arcunp.c'\" unpacked with wrong size!
  3115. fi
  3116. # end of 'arcunp.c'
  3117. fi
  3118. if test -f 'arcusq.c' -a "${1}" != "-c" ; then 
  3119.   echo shar: Will not clobber existing file \"'arcusq.c'\"
  3120. else
  3121. echo shar: Extracting \"'arcusq.c'\" \(2743 characters\)
  3122. sed "s/^X//" >'arcusq.c' <<'END_OF_FILE'
  3123. X/*
  3124. X * $Header: /var/local/hyc/src/arc/RCS/arcusq.c,v 2.0 1991/11/12 00:30:01 hyc Exp $
  3125. X */
  3126. X
  3127. X/*
  3128. X * ARC - Archive utility - ARCUSQ
  3129. X * 
  3130. X * Version 3.14, created on 07/25/86 at 13:04:19
  3131. X * 
  3132. X * (C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED
  3133. X * 
  3134. X * By:    Thom Henderson
  3135. X * 
  3136. X * Description: This file contains the routines used to expand a file which was
  3137. X * packed using Huffman squeezing.
  3138. X * 
  3139. X * Most of this code is taken from an USQ program by Richard Greenlaw, which was
  3140. X * adapted to CI-C86 by Robert J. Beilstein.
  3141. X * 
  3142. X * Language: Computer Innovations Optimizing C86
  3143. X */
  3144. X#include <stdio.h>
  3145. X#include "arc.h"
  3146. X
  3147. X#include "proto.h"
  3148. X
  3149. VOID        arcdie();
  3150. X
  3151. X/* stuff for Huffman unsqueezing */
  3152. X
  3153. X#define ERROR (-1)
  3154. X
  3155. X#define SPEOF 256        /* special endfile token */
  3156. X#define NUMVALS 257        /* 256 data values plus SPEOF */
  3157. X
  3158. extern struct nd {        /* decoding tree */
  3159. X    int        child[2];    /* left, right */
  3160. X}        node[NUMVALS];    /* use large buffer */
  3161. X
  3162. extern char    pinbuf[MYBUF];
  3163. extern u_char    outbuf[MYBUF], *outbeg, *outend;
  3164. X
  3165. static int    bpos;        /* last bit position read */
  3166. extern int    curin;        /* last byte value read */
  3167. static int    numnodes;    /* number of nodes in decode tree */
  3168. X
  3169. extern char  *inbeg, *inend;
  3170. X
  3171. X/* get a 16bit integer */
  3172. X#define GET_INT(x)    \
  3173. X{    x = (u_char) (*inbeg++); \
  3174. X    x |= *inbeg++ << 8;}
  3175. X
  3176. VOID
  3177. init_usq(f)            /* initialize Huffman unsqueezing */
  3178. X    FILE           *f;    /* file containing squeezed data */
  3179. X{
  3180. X    int        i;    /* node index */
  3181. X    u_int        inlen;
  3182. X
  3183. X    bpos = 99;        /* force initial read */
  3184. X
  3185. X    inlen = getb_unp(f);
  3186. X    inbeg = pinbuf;
  3187. X    inend = &pinbuf[inlen];
  3188. X
  3189. X    GET_INT(numnodes);
  3190. X
  3191. X    if (numnodes < 0 || numnodes >= NUMVALS)
  3192. X        arcdie("File has an invalid decode tree");
  3193. X
  3194. X    /* initialize for possible empty tree (SPEOF only) */
  3195. X
  3196. X    node[0].child[0] = -(SPEOF + 1);
  3197. X    node[0].child[1] = -(SPEOF + 1);
  3198. X
  3199. X    for (i = 0; i < numnodes; ++i) {    /* get decoding tree from
  3200. X                         * file */
  3201. X        GET_INT(node[i].child[0]);
  3202. X        GET_INT(node[i].child[1]);
  3203. X    }
  3204. X}
  3205. X
  3206. u_int
  3207. getb_usq(f)            /* get byte from squeezed file */
  3208. X    FILE           *f;    /* file containing squeezed data */
  3209. X{
  3210. X    int        i;    /* tree index */
  3211. X    u_int        j;
  3212. X
  3213. X    outbeg = outbuf;
  3214. X    for (j = 0; j < MYBUF; j++) {
  3215. X        /* follow bit stream in tree to a leaf */
  3216. X
  3217. X        for (i = 0; i >= 0;) {    /* work down(up?) from root */
  3218. X            if (++bpos > 7) {
  3219. X                if (inbeg >= inend) {
  3220. X                    inend = &pinbuf[getb_unp(f)];
  3221. X                    inbeg = pinbuf;
  3222. X                    if (inend == inbeg) {
  3223. X                        if (!curin)
  3224. X                            j--;
  3225. X                        return(j);
  3226. X                    }
  3227. X                }
  3228. X                curin = *inbeg++;
  3229. X                bpos = 0;
  3230. X
  3231. X                /* move a level deeper in tree */
  3232. X                i = node[i].child[1 & curin];
  3233. X            } else
  3234. X                i = node[i].child[1 & (curin >>= 1)];
  3235. X        }
  3236. X
  3237. X        /* decode fake node index to original data value */
  3238. X
  3239. X        i = -(i + 1);
  3240. X
  3241. X        if (i != SPEOF)
  3242. X            *outbeg++ = i;
  3243. X        else
  3244. X            break;
  3245. X    }
  3246. X    /*NOTREACHED*/
  3247. X    return (j);
  3248. X}
  3249. END_OF_FILE
  3250. if test 2743 -ne `wc -c <'arcusq.c'`; then
  3251.     echo shar: \"'arcusq.c'\" unpacked with wrong size!
  3252. fi
  3253. # end of 'arcusq.c'
  3254. fi
  3255. if test -f 'proto.h' -a "${1}" != "-c" ; then 
  3256.   echo shar: Will not clobber existing file \"'proto.h'\"
  3257. else
  3258. echo shar: Extracting \"'proto.h'\" \(410 characters\)
  3259. sed "s/^X//" >'proto.h' <<'END_OF_FILE'
  3260. u_int    getbuf PROTO ((FILE *f));
  3261. u_int    getb_ucr PROTO ((FILE *f));
  3262. u_int    getb_usq PROTO ((FILE *f));
  3263. u_int    getb_unp PROTO ((FILE *f));
  3264. VOID    hufb_tab PROTO ((u_char *buf, u_int len));
  3265. VOID     lzw_buf PROTO ((u_char *buf, u_int len, FILE *f));
  3266. VOID    putb_unp PROTO ((u_char *buf, u_int len, FILE *f));
  3267. VOID    putb_ncr PROTO ((u_char *buf, u_int len, FILE *f));
  3268. VOID    putb_pak PROTO ((u_char *buf, u_int len, FILE *f));
  3269. END_OF_FILE
  3270. if test 410 -ne `wc -c <'proto.h'`; then
  3271.     echo shar: \"'proto.h'\" unpacked with wrong size!
  3272. fi
  3273. # end of 'proto.h'
  3274. fi
  3275. if test -f 'tmclock.c' -a "${1}" != "-c" ; then 
  3276.   echo shar: Will not clobber existing file \"'tmclock.c'\"
  3277. else
  3278. echo shar: Extracting \"'tmclock.c'\" \(2332 characters\)
  3279. sed "s/^X//" >'tmclock.c' <<'END_OF_FILE'
  3280. X/*
  3281. X * Stolen from Jef Poskanzer's tws time library, which was stolen from
  3282. X * Marshall Rose's MH Message Handling system...
  3283. X *
  3284. X * tmclock() will convert time from a tm struct back to a clock value.
  3285. X * tmjuliandate() converts a tm struct to its julian day number.
  3286. X * tmsubdayclock() takes hours, minutes, and seconds from a tm struct
  3287. X * and returns the number of seconds since midnight of that day. (?)
  3288. X *  -- Howard Chu, August 1 1988      hyc@umix.cc.umich.edu, umix!hyc
  3289. X */
  3290. X
  3291. X/* $Header: /var/local/hyc/src/arc/RCS/tmclock.c,v 2.0 1991/11/12 08:02:25 hyc Exp $ */
  3292. X
  3293. X/* Julian day number of the Unix* clock's origin, 01 Jan 1970. */
  3294. X#define JD1970 2440587L
  3295. X#define    CENTURY    19
  3296. X#if    BSD
  3297. X#include <sys/time.h>
  3298. X#else
  3299. X#include <time.h>
  3300. extern long    timezone;    /* should be in <time.h>, but isn't on Sun */
  3301. X#endif
  3302. X
  3303. long    tzone;
  3304. X
  3305. long
  3306. tmjuliandate( tm )
  3307. struct tm *tm;
  3308. X    {
  3309. X    register int mday, mon, year;
  3310. X    register long a, b;
  3311. X    double jd;
  3312. X
  3313. X    if ( (mday = tm -> tm_mday) < 1 || mday > 31 ||
  3314. X        (mon = tm -> tm_mon + 1) < 1 || mon > 12 ||
  3315. X        (year = tm -> tm_year) < 1 || year > 10000 )
  3316. X    return ( -1L );
  3317. X    if ( year < 100 )
  3318. X    year += CENTURY * 100;
  3319. X
  3320. X    if ( mon == 1 || mon == 2 )
  3321. X    {
  3322. X    --year;
  3323. X    mon += 12;
  3324. X    }
  3325. X    if ( year < 1583 )
  3326. X    return ( -1L );
  3327. X    a = year / 100;
  3328. X    b = 2 - a + a / 4;
  3329. X    b += (long) ( (double) year * 365.25 );
  3330. X    b += (long) ( 30.6001 * ( (double) mon + 1.0 ) );
  3331. X    jd = mday + b + 1720994.5;
  3332. X    return ( (long) jd );
  3333. X    }
  3334. X
  3335. X
  3336. long
  3337. tmsubdayclock( tm )
  3338. struct tm *tm;
  3339. X    {
  3340. X    register int sec, min, hour;
  3341. X    register long result;
  3342. X#if    BSD
  3343. X    {
  3344. X       struct timezone tzp;
  3345. X
  3346. X       gettimeofday(0L, &tzp);
  3347. X       tzone = tzp.tz_minuteswest*(-60);
  3348. X    }
  3349. X#else
  3350. X    tzone=timezone;
  3351. X#endif
  3352. X    if ( (sec = tm -> tm_sec) < 0 || sec > 59 ||
  3353. X        (min = tm -> tm_min) < 0 || min > 59 ||
  3354. X        (hour = tm -> tm_hour) < 0 || hour > 23 )
  3355. X    return ( -1L );
  3356. X
  3357. X    result = ( hour * 60 + min ) * 60 + sec;
  3358. X    result -= tzone;
  3359. X
  3360. X    return ( result );
  3361. X    }
  3362. X
  3363. X
  3364. long
  3365. tmclock( tm )
  3366. struct tm *tm;
  3367. X    {
  3368. X    register long jd, sdc;
  3369. X    long result;
  3370. X
  3371. X    if ( ( jd = tmjuliandate( tm ) ) == -1L )
  3372. X    return ( -1L );
  3373. X    if ( ( sdc = tmsubdayclock( tm ) ) == -1L )
  3374. X    return ( -1L );
  3375. X
  3376. X    result = ( jd - JD1970 ) * 24 * 60 * 60 + sdc;
  3377. X
  3378. X    if ( localtime( &result )->tm_isdst )
  3379. X    result -= 60L * 60L;
  3380. X
  3381. X    return ( result );
  3382. X    }
  3383. END_OF_FILE
  3384. if test 2332 -ne `wc -c <'tmclock.c'`; then
  3385.     echo shar: \"'tmclock.c'\" unpacked with wrong size!
  3386. fi
  3387. # end of 'tmclock.c'
  3388. fi
  3389. echo shar: End of archive 1 \(of 3\).
  3390. cp /dev/null ark1isdone
  3391. MISSING=""
  3392. for I in 1 2 3 ; do
  3393.     if test ! -f ark${I}isdone ; then
  3394.     MISSING="${MISSING} ${I}"
  3395.     fi
  3396. done
  3397. if test "${MISSING}" = "" ; then
  3398.     echo You have unpacked all 3 archives.
  3399.     rm -f ark[1-9]isdone
  3400. else
  3401.     echo You still need to unpack the following archives:
  3402.     echo "        " ${MISSING}
  3403. fi
  3404. ##  End of shell archive.
  3405. exit 0
  3406.